Thursday, May 28, 2015


Hi all in this post I will explain you how we can use WSO2 ESB to send files across network via SMB (Server Message Block) protocol.

WSO2 ESB has neat features like vfs and well equipped in many protocols including SMB. So in this post I will show you how to read a file and finally how to send it via VFS to an SMB Windows endpoint.

In order to VFS to work you need to enable VFS receivers and senders in axis2.xml. To do so navigate to <ESB_HOME>/repository/conf/axis2/axis2.xml and uncomment the following lines.


<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>
<transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>

After enabling VFS you can create a proxy service as follows.



<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="VFSSMB"
       transports="https http vfs"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target>
      <inSequence>
         <log>
            <property name="ADI FTP" value="'file transfer...'"/>
         </log>
      </inSequence>
      <outSequence/>
      <faultSequence/>
   </target>
   <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
   <parameter name="transport.PollInterval">5</parameter>
   <parameter name="transport.vfs.FileURI">vfs:smb://Administrator:wso2pass@192.168.28.79/smbshare/in</parameter>
   <parameter name="transport.vfs.MoveAfterProcess">vfs:smb://Administrator:wso2pass@192.168.28.79/smbshare/out</parameter>
   <parameter name="transport.vfs.FileNamePattern">.*\.txt</parameter>
   <parameter name="transport.vfs.ContentType">text/plain</parameter>
   <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
   <parameter name="transport.vfs.MaxRetryCount">3</parameter>
</proxy>


Here the proxy service will Poll the source directory after the given interval and read files if there are any and move them to the destination directory.

Monday, May 25, 2015





PTT (Pass Through Transport) transport is the default transport that is shipped with ESB (At the time of this post ESB 4.9.0) It is the recommended transport which brings blistering fast performance to WSO2 ESB, you can read more about this from here. But the old HTTP-NIO transport also ships with the ESB by default and it's disable in the default pack, in some scenarios you might need to enable this transport.

HTTP-NIO transport is a module of the Apache Synapse project. The two classes that implement the receiver and sender APIs are org.apache.synapse.transport.nhttp.HttpCoreNIOListener and org.apache.synapse.transport.nhttp.HttpCoreNIOSender respectively. These classes are available in the JAR file named synapse-nhttp-transport.jar. The transport implementation is based on Apache HTTP Core - NIO and uses a configurable pool of non-blocking worker threads to grab incoming HTTP messages off the wire. You can read more about NHTTP from here.

Enabling nhttp is very simple, and I'm writing this down if some one couldn't find out how to do this.

In-order to enable NHTTP follow the instructions below,

1. Shutdown the server if already running
2. Navigate to <WSO2_HOME>/repository/conf/axis2 directory.
3. Now take a backup of axis2.xml file and delete that file.
4. Now rename the axis2_nhttp.xml to axis2.xml.
5. Now start the Server again.

For NTTP different set of configuration are used and these reside in the axis2_nhttp.xml file, by default this is disabled and when the axis2.xml is replaced with the axis2_nhttp.xml these configuration takes effect.


In this post I'll explain you how to change the defalut ports of WSO2 Products to system default ports 443 and 80.
You can change the ports used for services (i.e. APIs , proxies) by changing the http and https transport receivers declared in
 <PRODUCT>/repository/conf/axis2/axis2.xml  as shown below.

HTTP Receiver


<transportReceiver name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpListener">
<parameter name="port" locked="false">80</parameter>
<parameter name="non-blocking" locked="false">true</parameter>
<!-parameter name="bind-address" locked="false">hostname or IP address</parameter->
<!-parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter->
<parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.PassThroughNHttpGetProcessor</parameter>
<!-<parameter name="priorityConfigFile" locked="false">location of priority configuration file</parameter>->
</transportReceiver>

HTTPS Receiver


<transportReceiver name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener">
<parameter name="port" locked="false">443</parameter>
<parameter name="non-blocking" locked="false">true</parameter>
<!-
parameter name="bind-address" locked="false">hostname or IP address</parameter
->
<!-
parameter name="WSDLEPRPrefix" locked="false">https://apachehost:port/somepath</parameter
->
<parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.PassThroughNHttpGetProcessor</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="SSLVerifyClient">require</parameter>
supports optional|require or defaults to none -->
</transportReceiver>

And if you need to configure the ports used by carbon admin console and other apps (i.e. APIStore, Publisher) you need to change the HTTP and HTTPS connector protocol configurations of catalina-server.xml file in

 <PRODUCT>/repository/conf/tomcat/catalina-server.xml.


<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="80"
redirectPort="443"
bindOnInit="false"
maxHttpHeaderSize="8192"
acceptorThreadCount="2"
maxThreads="250"
minSpareThreads="50"
disableUploadTimeout="false"
connectionUploadTimeout="120000"
maxKeepAliveRequests="200"
acceptCount="200"
server="WSO2 Carbon Server"
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
URIEncoding="UTF-8"/>

<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
bindOnInit="false"
sslProtocol="TLS"
maxHttpHeaderSize="8192"
acceptorThreadCount="2"
maxThreads="250"
minSpareThreads="50"
disableUploadTimeout="false"
enableLookups="false"
connectionUploadTimeout="120000"
maxKeepAliveRequests="200"
acceptCount="200"
server="WSO2 Carbon Server"
clientAuth="false"
compression="on"
scheme="https"
secure="true"
SSLEnabled="true"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/javascript,application/x-javascript,application/javascript,application/xml,text/css,application/xslt+xml,text/xsl,image/gif,image/jpg,image/jpeg"
URIEncoding="UTF-8"/>

This is all and Please drop a comment if you have any queries. 

Tuesday, May 19, 2015




Although XPATH 2.0 is supported in WSO2 ESB, it is not enabled by default. In order to use this you have to enable XPATH 2.0.

To enable XPath 2.0 functions, we have to uncomment following entry in the synapse.properties file. which is located at <ESB_HOME>/repository/conf directory

synapse.xpath.dom.failover.enabled=true

After enabling xpath 2.0, you will able to use xpath functions like "codepoint-equal()" in your synapse configuration.

If you are using synapse specific xpath functions like "get-property()" within a xpath 2.0 function you have to use them with the prefix "syn".

Following is an example for a such usage.

So in my case lets say I'm getting a request header like following

{org.apache.synapse.transport.http.wire} -  >> "Content-Type: application/xml; charset=UTF-8" {org.apache.synapse.transport.http.wire}


I want to extract the "application/xml" value from the "application/xml; charset=UTF-8". I can use the following expression to do this, Note that I'm tokenizing the mentioned value, extracting the relevent text and assigning it to a new property which can be referred later.



<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:fn="http://www.w3.org/2005/xpath-functions" name="NEW_CONTENT_TYPE" expression="fn:tokenize(syn:get-property('axis2','ContentType'),';')[1]" scope="default" type="STRING"/>


Thanks for reading and drop a comment if you have any queries.




Saturday, May 9, 2015


There might be some use cases where a user wants to expose WSO2 API-Manager store over HTTP. Users can access the store via HTTP endpoint, but when the user is trying to login the user will be directed to the HTTPS endpoint.

And this is not recommended as well, if the Store is used over HTTP when authenticating the user credentials will be sent to the back-end as plain text. This can be a major sicurity issue when it comes to a production environment. So you should keep this in mind as well.

Since this is not supported by WSO2 API Manager we will have to do some code level changes. Just few lines. I will do the code change in a way that both HTTP and HTTPs endpoints can be used. If the user is accessing the HTTP endpoint everything will route over HTTP and if HTTPs endpoint is used the routing will take place throuch that EP.

WSO2 API Manager Version I'm Using : 1.8. You can read more about WSO2 API Manager from here.

So lets get started

1. Open the following file,

AM_HOME/wso2am-1.8.0/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templates/ui/dialogs/template.jag

and place the following code. Or you can get a diff and do the code changes manually.

<% jagg.template("ui/dialogs", function(inputs, outputs, jagg){
var i18n = require("i18n");
var localeResourcesBasePath="/site/conf/locales/jaggery/";
i18n.init(request,localeResourcesBasePath);

%>
<script type="text/javascript">
        var isSecure = true;
        var showLogin = <%=session.get("showLogin")%>;
        var redirectToHTTPS = '<%=session.get("redirectToHTTPS")%>';

    </script>
 <%     var mod,httpUrl,httpsUrl;
        mod = jagg.module("manager");

        httpsUrl= mod.getHTTPsURL();
        var httpsURL =  httpsUrl + request.getRequestURI();

        if(request.getQueryString()){
            httpsURL += "?" + request.getQueryString();
        }

        session.put("showLogin","false");
        session.put("redirectToHTTPS","");
 %>
<div class="modal fade" id="messageModal"></div>
<div id="login-data" style="display:none;">

    <form id="mainLoginForm" autocomplete="off">
        <div class="modal-header">
            <button class="close" data-dismiss="modal">x</button>
            <h3><%=i18n.localize("login")%></h3>
        </div>

        <!--Error message viewer-->
        <div class="alert alert-error" id="loginErrorMsg" style="display:none">
            <div class="theMsg"></div>
        </div>

        <div class="modal-body">
            <label><%=i18n.localize("username")%>:</label>
            <input type="text" id="username" name="name" class="span3" placeholder="<%=i18n.localize("usernamePlcHolder")%>"/>
            <label><%=i18n.localize("password")%>:</label>
            <input type="password" id="password" name="pass" class="span3"/>
            <input type="hidden" id="tenant" name="tenant" value="<%=request_tenant%>">


        </div>
        <div class="modal-footer">
            <a href="#" class="btn btn-primary" id="loginBtn"><%=i18n.localize("login")%></a>
            <a href="#" class="btn" data-dismiss="modal"><%=i18n.localize("cancel")%></a>
        </div>
    </form>
</div>


<div id="confirmation-data" style="display:none;">
    <div class="modal-header">
        <button class="close" data-dismiss="modal">x</button>
        <h3 class="modal-title">Modal header</h3>
    </div>
    <div class="modal-body">
        <p>One fine body</p>
    </div>
    <div class="modal-footer">
        <a href="#" class="btn btn-primary">Save changes</a>
        <a href="#" class="btn btn-other" data-dismiss="modal">Close</a>
    </div>
</div>
<% }); %>


2. Now open the following file and replace with the following code.

AM_HOME/wso2am-1.8.0/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templates/user/login/template.jag

<% jagg.template("user/login", function(inputs, outputs, jagg) {
var i18n = require("i18n");var publisherUrl;
var localeResourcesBasePath="/site/conf/locales/jaggery/";
i18n.init(request,localeResourcesBasePath);
%>
<% var user = outputs.user; %>
<%
        var isSuperTenant, tenantDomain;
        var mod = jagg.module("manager");
        var httpsUrl= mod.getHTTPsURL();
  var isSelfSignupEnabled = mod.isSelfSignupEnabledForTenantUser(request_tenant);
    var log = new Log();

        var currentURL = request.getRequestURI();
        if(request.getQueryString()){
            currentURL += "?" + request.getQueryString();
        }
        var tenant=request_tenant;
        var urlPrefix;
        if(tenant!=null) {urlPrefix="tenant="+tenant;}else{urlPrefix='';}
        
        if (jagg.getUser() != null) {
         isSuperTenant = jagg.getUser().isSuperTenant;
   tenantDomain = jagg.getUser().username.split('@')[1];
        }
        


%>
<% if(user) { %>

<%if(jagg.getUser().hasPublisherAccess){%>
<%publisherUrl = jagg.module("manager").getAPIPublisherURL().url;
<%}%>
<ul class="nav actions login-sign-up pull-right">
            <li class="dropdown settingsSection">
                <i class="fa fa-tachometer"></i>
                                <br>
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Themes <b class="caret"></b></a>
              <ul class="dropdown-menu theme-container">
                <li  class="themeSelection"><h3><%=i18n.localize("selectTheme")%></h3>
                    <form id="themeSelectForm" action="<%=jagg.getAbsoluteUrl(jagg.getThemeFile("templates/user/theme/template.jag?theme=modern"))%>">
                        <input type="hidden" id="themeToApply" name="themeToApply" />
                        <input type="hidden" id="subthemeToApply" name="subthemeToApply" />
                        <input type="hidden" id="pathToSend" name="pathToSend" value="<%=currentURL%>" />
                        <table class="table">
                            <tr>
                                <td>
                                    <div class="thumbnail <% if(jagg.getUserTheme().base == "fancy" && jagg.getUserTheme().subtheme == null) { %>currentTheme<% } %>">
                                        <a data-theme="fancy" data-subtheme="" class="badge themeLabel" onclick="applyTheme(this)">
                                            <img src="<%=jagg.getAbsoluteUrl(jagg.getThemeFile("images/thumb-fancy.png"))%>" />
                                            <br /><div class="themeName"><%=i18n.localize("fancy")%></div>
                                        </a>
                                    </div>

                                </td>
                                <td>
                                    <div class="thumbnail <% if(jagg.getUserTheme().base == "dark" && jagg.getUserTheme().subtheme == null) { %>currentTheme<% } %>">
                                        <a data-theme="fancy" data-subtheme="dark" class="badge themeLabel" onclick="applyTheme(this)">
                                            <img src="<%=jagg.getAbsoluteUrl(jagg.getThemeFile("images/thumb-dark.png"))%>" />
                                            <br /><div class="themeName"><%=i18n.localize("dark")%></div>
                                        </a>
                                    </div>

                                </td>
                            </tr>
                        </table>
                    </form>
                </li>
              </ul>
            </li>
           <li class="divider-vertical"></li>
           <li class="dropdown">
               <i class="fa fa-user"></i>
               <br>
               <a class="link-to-user dropdown-toggle" data-toggle="dropdown"><%=user.username%> <b class="caret"></b></a>
             <ul class="dropdown-menu" id="userInfoMenu">
               <li class="userInfoSection">
                   <%=i18n.localize("logged")%> <h4><%=user.username%></h4>
               </li>
               <li class="logout-link-special"><button id="logout-link" class="btn btn-danger"><%=i18n.localize("logout")%></button></li>
             </ul>
           </li>
</ul>
<% } else { %>
<ul class="nav actions login-sign-up pull-right">
<%
var tenant=request_tenant;
if(isSelfSignupEnabled){%>
    <li>
        <i class="fa fa-pencil-square-o"></i>
        <br>
 <% if(site.request_url=="READ_FROM_REQUEST") { %>
 <a id="register-link" href="<%=site.context%>/site/pages/sign-up.jag?<%=urlPrefix%>"><%=i18n.localize("signup")%></a>
 
 <% } else {
     %>
 <a id="register-link" href="<%=site.request_url%>/site/pages/sign-up.jag?<%=urlPrefix%>"><%=i18n.localize("signup")%></a>
 
 <% } %>
    </li>
 <%}%>
    <li>
        <i class="fa fa-user"></i>
        <br>
        <a id="login-link"><%=i18n.localize("login")%></a>
    </li>
</ul>
<% } %>
<!--Links to Access Tenant Store and Public Store-->
<div class="tenant-position-setter">
<%if(jagg.getUser()!=null){%>
 <!--Links to Access Tenant Store and Public Store-->
  <%if (jagg.getUser().hasPublisherAccess) {%>
   Go to <a href="<%=publisherUrl%>" target="_blank" ><%=i18n.localize("apipublisher")%></a>
           <%if(site.showPublicStoreURL){%>
           |

  <%}}%>
 <%}%>

  <%if (tenant == null && isSuperTenant != null && !isSuperTenant && site.showPublicStoreURL) {%>

    Go to <a href="<%=jagg.getAbsoluteUrl("/")%><%="?tenant=" + tenantDomain%>"><%=tenantDomain%><%=i18n.localize("apistoreDesc")%></a>


  <%} else if ((tenant != null)&& site.showPublicStoreURL){%>

   Go to <a href="<%=jagg.getAbsoluteUrl("/")%>"><%=i18n.localize("publicAPIStore")%></a>


  <%}%>


 </div>

<% }); %>

3. Again open the following file and replace with following code. Or do the changes manually.

AM_HOME/wso2am-1.8.0/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templates/user/sign-up/template.jag

<% jagg.template("user/sign-up", function(inputs, outputs, jagg) { %>
<%
 var fields = outputs.fields, length = fields.length;
        var user = session.get("logged.user");
        var mod = jagg.module("manager");
        var httpsUrl= mod.getHTTPsURL();
        if(user){ %>
        <script>
            location.href = "<%=site.context%>";
        </script>
        <% } %>
        <script>
            var context= "<%=site.context%>";
        </script>
<div class="title-section"><h2><%=i18n.localize("signupTitle")%></h2></div>
<div class="content-section shadow-up">
<div class="content-data">
<form class="form-horizontal" id="sign-up" autocomplete="off">
<fieldset>
    <div class="control-group">
        <label class="control-label"  for="newUsername"><%=i18n.localize("username")%>:<span class="requiredAstrix">*</span></label>
        <div class="controls">
            <input id="newUsername" name="newUsername" minlength="5" type="text" class="required validName input-medium noSpace" />
            <%              
                if(request_tenant != null) { %>
                     <label class="lblTenantDomainName"  for="newUsername"> @<%=request_tenant%></label>
            <%    }
            %>
           
            <input id="hiddenTenantDomain" type="hidden" value="<%=request_tenant%>"> 
        </div>
    </div>

    <div class="control-group">
        <label class="control-label" for="newPassword"><%=i18n.localize("password")%>:<span class="requiredAstrix">*</span></label>
        <div class="controls">
            <div class="row-fluid">
                    <div class="span6">
                        <input type="password" class="input-large password" id="newPassword" name="newPassword" />

                        <div class="help-block" id="password-help" style="display:none">
                          <%=i18n.localize("pwHelpMsgLine1")%>
                            <ul>
                                <li><%=i18n.localize("pwHelpMsgLine2")%></li>
                                <li><%=i18n.localize("pwHelpMsgLine3")%></li>
                                <li><%=i18n.localize("pwHelpMsgLine4")%></li>
                                <li><%=i18n.localize("pwHelpMsgLine5")%></li>
                            </ul>

                        </div>
                    </div>
                    <div class="span6">
                        <div class="password-meter" style="display:none;">
                            <div class="password-meter-message"></div>
                            <div class="password-meter-bg">
                                <div class="password-meter-bar"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
    </div>



    <div class="control-group">
            <label class="control-label" for="newPasswordConfirm"><%=i18n.localize("retypePassword")%>:<span class="requiredAstrix">*</span></label>
            <div class="controls"><input type="password" class="matchPasswords input-large" id="newPasswordConfirm" /></div>
    </div>
    
    <%
        var i, field, inputClass;
        for(i = 0; i < length; i++) {
            field = fields[i];
            var required = field.required;
            var claimUri = field.claimUri;
            if (required == true) {
             inputClass = "required input-large";
            } else {
             inputClass = "input-xlarge";
            }
            if (claimUri.indexOf("name") !== -1) {
             inputClass = "required validName input-large noSpace";
            } else if (claimUri.indexOf("email") !== -1) {
             inputClass = "required validEmail input-large noSpace";
            } 
    %>
 <%if (required == true) {%>
         <div class="control-group">
            <label class="control-label" for="<%=i%>cliamUri"><%=i18n.localize(field.name, field.name)%>:
             <span class="requiredAstrix">*</span>
            </label>
            <div class="controls"><input type="text" id="<%=i%>cliamUri" name="<%=i%>cliamUri" class="<%=inputClass%>"/></div>
     </div>
  <%} %>
    <% } %>
        <div class="controls" style="padding-bottom:10px;" id="moreFieldsLink"><a onclick="showMoreFields()"><i class="icon-plus-sign"></i>More Details</a></div>
 <div class="controls" id="hideFieldsLink" style="display:none;padding-bottom:10px;">
  <a onclick="hideMoreFields()">
  <i class="icon-minus-sign"></i>More Details</a>
 </div>
        <div id="moreFields" style="display:none">
  <%  
  for(i = 0; i < length; i++) {
              field = fields[i];
              var required = field.required;
              var claimUri = field.claimUri;
   if(field.name == "Home Phone" || field.name == "Telephone") {
    field.name = "Land Phone";
   } else if (field.name == "Mobile") {
    field.name = "Mobile Phone";
   }
   if (claimUri.indexOf("address") !== -1) {
    inputClass = "input-address";
              } else if (claimUri.indexOf("country") !== -1) {
    inputClass = "input-medium";
       } else if (claimUri.indexOf("role") !== -1) {
    inputClass = "input-small";
       } else {
    inputClass = "input-large";
   }
  %>
   <%if (required != true) {%>
            <div class="control-group">
                <label class="control-label" for="<%=i%>cliamUri"><%=i18n.localize(field.name, field.name)%>:
                </label>
                <div class="controls"><input type="text" id="<%=i%>cliamUri" name="<%=i%>cliamUri" class="<%=inputClass%>"/></div>
        </div>
    <%} %>
  <% } %>
 </div>
 <input type="hidden" id="fieldCount" name="fieldCount" value="<%=length%>"/>
    <div class="form-actions">
        <input class="submit btn btn-primary" type="submit" value="<%=i18n.localize("submit")%>"/>

    </div>
</fieldset>
      </form>
</div>
</div>
<form id="signUpRedirectForm" method="post" action="<%=jagg.getAbsoluteUrl(jagg.getThemeFile("templates/user/sign-up/redirector.jag"))%>">
        <input type="hidden" name="redirectToHome" id="redirectToHome" value="<%=site.context%>" />
</form>


<% }); %>


4. Now refresh the page and you will be able to access the store via both HTTP and HTTPS.

Thanks for reading and please drop a comment if you have any queries.



Subscribe to RSS Feed Follow me on Twitter!