Tuesday, 5 April 2016

Mule HttpListener Example

Mule Runtime 3.6 and later version have deprecated old Http Connector with , new Http Listener Config . Let's take an example to see how we can use it .This example also demonstrates how to get a particular xml element without using JAXB .

This example app will listen to a particular host and port , for post method , and parses the request xml using xpath . Based on the xml , we return the response based on the input xml received in request .

This is our mule config xml :
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
 xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.6.1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd">

<http:listener-config port="8081" host="0.0.0.0" name="myRequestConfig" >
 <http:worker-threading-profile maxThreadsActive="15"/>
</http:listener-config>

<flow name="SimpleTest" >
<http:listener path="/abc" config-ref="myRequestConfig" allowedMethods="PATCH"/>
<logger category="d" level="ERROR" message="xpath: #[xpath3('/isCancelled')]"/>

<choice >
<when expression="#[xpath3('/isCancelled') == 'true']">
 <set-payload value="SUCCESSS"></set-payload>
</when>
<otherwise>
 <set-payload value="FAIL"></set-payload>
</otherwise>
</choice>
</flow>

</mule>
Now we can see that traditional http inbound endpoint and http connector is replaced with Http Listener and Http Listener Config respectively . The major difference is that we can not use service overrides in Http listener config like we used to do in http connector , also http listener does not return MULE_SESSION in response headers .If we use http listener , all outbound property will automatically be converted in http response headers . You can use allowedMethods attribute to configure different Http methods . We can have multiple http listener , referencing to same listener config . Multiple flows with same path but different methods is also allowed .

Post Comments And Suggestions .!!!



Wednesday, 9 December 2015

How to Generate Barcode 128 In Java

For generating Barcodes , we can use Barcode4j library , which is opensource and free library . Let's look at some java code to generate barcode as image in java .

First of all , enter following dependency in your pom.xml.
<dependency>
 <groupId>net.sf.barcode4j</groupId>
 <artifactId>barcode4j</artifactId>
 <version>2.1</version>
   
   </dependency>

You can also download the jar from here if you are using it in a standalone java program .

Now here is the sample java program which generates the barcode 128 with codeset B and save it as a png file.

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.impl.code128.Code128Constants;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;


public class MainClass2 {
  
  public static void main(String[] args) throws IOException {
    
    String barcodeString = "4888575";
    Code128Bean barcode128Bean = new Code128Bean();
    
    
    barcode128Bean.setCodeset(Code128Constants.CODESET_B);
    final int dpi = 100;

  //Configure the barcode generator
    //adjust barcode width here
  barcode128Bean.setModuleWidth(UnitConv.in2mm(5.0f / dpi)); 
  barcode128Bean.doQuietZone(false);

  //Open output file
  File outputFile = new File("G:/barcode.png");
  OutputStream out = new FileOutputStream(outputFile);
  try 
  {
      BitmapCanvasProvider canvasProvider = new BitmapCanvasProvider(
              out, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);

      barcode128Bean.generateBarcode(canvasProvider,barcodeString);

      canvasProvider.finish();
  } 
  finally 
  {
      out.close();
  }
    
  }

}

Barcode4J supports other formats like EAN-128, GS1-128 , Code 39 etc as well .


Provide comments and suggestions !!!



Sunday, 22 November 2015

HOW TO SETUP NFS MOUNT IN LINUX

NFS mount is used to share a directory between several servers, It saves the disk Space and is Useful for a Infrastructure where a application shares a common directory and is hosted in multiple instances.

Lets think we have a Rails application where we upload a csv file and save it a directory in server with file name to DB .

On the other hand a Rake Task/ Cron Job runs every two minutes that polls DB for file name and proccess the CSV file to get the desired response.

It works fine when we have a single instance hosted in server, think if we have two instances of Rails in different Server and is managed by a Load balancer to server request.

When a File Upload Request comes to ELB , it directs to instance1 with file1 and the second request to instance 2 with file2, The cron job in instance 2 picks the file name file1 from DB and doesnot found any matching file and Marks FILE NOT FOUND IN DB , where as file is present in instance1.

To avoid this type of issues we can use S3 which we can get py paying few amount, the Opensource way is Using NFS Mount, Lets Check how to Configure NFS.

Lets Say we have two instances with IP:
10.23.225.16
10.23.225.17

Lets Configure
NFS-Master :  10.23.225.16
NFS - Client :  10.23.225.17

MASTER SETUP :
Execute the following Commands:
sudo su 
yum install nfs-utils nfs-utils-lib
Startup Scripts :

chkconfig nfs on 
service rpcbind start 
service nfs start

EXPORT the Shared Directory :

Suppose we want the directory /home/rails/upload_dir , to be shared between the instances.

Open vi /etc/exports
Add the following lines at EOF
/home/rails/upload_dir 10.23.225.17(rw,sync)
then execute :
exportfs -a
service nfs restart
CLIENT SETUP :
SSH to server 10.23.225.17

Execute following commands:

yum install nfs-utils nfs-utils-lib
#Assuming the upload_dir path is same as instance1
mkdir -p /home/rails/upload_dir
mount 10.23.225.26:/home/rails/upload_dir /home/rails/upload_dir

You Can verify it by typing:
df –h
Filesystem            Size  Used Avail Use% Mounted on /dev/sda               20G  783M   18G   5% / 10.23.225.16:/home/rails/upload_dir 20G  785M   18G   5% /home/rails/upload_dir
TO ENSURE IT IS ALWAYS MOUNTED MAKE CHANGES IN FS TAB:
nano /etc/fstab
Add the following line:
10.23.225.16:/home/rails/upload_dir  /home/rails/upload_dir nfs      defaults,_nfs_shared 0 0
Try creating a file in instace1 of shared dir and check it should be populated in instance2 of shared dir(/home/rails/upload_dir)

Keep in Mind Once the NFS Mount is unmounted all the data will be lost from the mounted instance , but data will be safe in Master instance.

This post is created by Santosh Mohanty . You can contact him for any questions at santa.jyp@gmail.com or message him on his linkedIn profile .


Tuesday, 17 November 2015

Search And Replace String in ByteBuffer

This is a simple java program which will search and replace a particular String in ByteBuffer
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;


public class ByteBufferTest {
  
  public static void main(String[] args)
  {
    String fullText = "javarootsbestwebsiteoftheyear";
    String search = "website";
    String replace = "blog";
    ByteBuffer input = ByteBuffer.wrap(fullText.getBytes());
    byte[] toSearch = search.getBytes();
    int index = getIndex(input, toSearch);
    
    byte[] first = new byte[index];
    input.get(first);
    
    byte[] second = replace.getBytes();
    
    input.position(input.position()+search.length());
    
    ByteBuffer finalOne = ByteBuffer.allocate(first.length+second.length+input.remaining());
    finalOne.put(first);
    finalOne.put(second);
    finalOne.put(input);
    finalOne.flip();
    
    CharBuffer result = Charset.forName("UTF-8").decode(finalOne);
    String s = result.toString();
    System.out.println(s);
    
    
  }
  
  public static int getIndex(ByteBuffer input , byte[] toSearch)
  {
    int index = -1 ;
    while(input.hasRemaining() && index==-1)
    {
      boolean found = true ;
      for(byte b : toSearch)
      {
        if(input.get()!=b)
        {
          found = false ;
          break ; 
        }
      }
      if(found)
      {
        index= input.position()-toSearch.length;
      }
    }
    input.rewind();
    return index ;
  }

}

Post Comments And Suggestions !!!




Monday, 9 November 2015

Beginners Guide to Jenkins

In this blog we will be learning how to use Continuous Integration tools to deploy Projects, Here I will be using Jenkins as CI and Maven as build tool to deploy Spring MVN Based Applications.
STEP 1:
You can Install Jenkins through yum/apt-get for your Linux/Redhat Distributions, but I prefer to install jenkins as a home user so that it can access my tools like java,maven,capistrano,ruby,pscp and many different tools.

My Home directory here is /home/rails

Jenkins will be installed under /home/rails/.jenkins

To do this I will download the Jenkins.war file from jenkins repo

STEP 2 :
Execute the war file using this command

java -jar jenkins.war --httpPort=8080
You will view the following lines
Nov 05, 2015 1:14:43 AM hudson.WebAppMain$3 run
INFO: Jenkins is fully up and running

Access Jenkins through localhost:8080
You should View a Wonderful Jenkins Dashboard.
STEP 3 :

Create a User who can create jobs and build those, Let me make it easier for you:
•Click on Manage Jenkins => Configure Global Security
•Enable Security => Jenkins Own user Database.
•Under Authorization part, select Matrix based Security, For Anonymous User Under View select only Read Permission
•Now Click on Add and create a user named Admin and Grant All Access
•Click Save and Apply
•You will be redirected to Set up page enter your password and click Save.

Step 4:

Manage Plugins:

By Default Jenkins comes in with prebuilt plugins like svn, maven,scp for installing extra plugins you can go to availables tab and install.

Step 5:

Accessing Repository to download source code and build
•Here I will be using SVN & SSH
•As I am in my home directory I will be using my ~/.ssh/id_rsa Keys for Authentication
•Click on Add Credentials => Global Credential and enter your credentials
•Repo url: svn+ssh://svn@svn.corporate.com/projects
•SSH Authentication
Username : svn
Passphrase: ****** (Null if no Passphrase)
Private Key : Upload your id_rsa Key

Step 6:

Click on Create Job:
•Type Project Name
•Enter SVN Repo details
•Build => Invoke Top Level Maven Target
•Use Maven Version as Default
•Goal : clean -Dmaven.test.skip=true package -P prod
•Apply and Save.
Now Its Done.
If you need to send the build to some other location Enter your script in command shell this would do the Work.
Step 7:

Click on Build Now, The Build Should Work for you.

Now it should show you a success message.

Jenkins + Capistrano Integration Coming Soon.

This post is created by Santosh Mohanty . You can contact him for any questions at santa.jyp@gmail.com or message him on his linkedIn profile .


Wednesday, 2 September 2015

Why You Should Move to Rails 5

Every one of us is waiting for a new and clean release of Rails 5 , which not only accepts the SPA(Single Page Application) Implementation easily but also has enhanced the performance and structure of thr most popular Rails frame work.

The release of Rails 5 is supposed to be fall on summer/fall of 2015.

Lets discuss the rich changes/implementation of Rails 5.

MERGING RAILS API

SPA is on rise, while developing a Single page application we rails developers faced a lot of issues, the routing was lacked and there were several security vulnerabilities that we had to handle.

In Rails 5, the rails-api Gem will be merged into core allowing the use of Rails as Simple JSON API. Which ease building API using Javascript Library.

NO MORE RAKE COMMANDS

In Rails 5 all the current rake commands will be accessible via the rails command.
When you want to run a migration, you will type rake db:migrate in Rails 4. In Rails 5 this will become railsdb:migrate.
The reason for this change is that currently it's not very logical which command has to go through rake and which command should go through rails. When you're working with rails for a longer time it becomes second nature, but only because you remember it.
For a newcomer, this is a big problem and makes learning rails confusing.
See this issue on GitHub for more details .

WHEN TO USE RAKE

You can now restart all of your apps with the command rake restart.
See this Pull Request for more details .

TEST CASES CHANGES

In Rails 5, the test helpers assigns() and assert_template() will be deprecated. Its because testing instance variable and what template is being called smells bad. These are internals of controller and controller tests should not care about what vars I set.
Controllers test are concerned about HTTP,Cookies, Renders, Redirects and so on.
More Details can be found here .

BLOOMING RUBY 2.2.1

Rails will only support Ruby 2.2.1 and up. Since it wants to be able to leverage all the speed improvements in the newer ruby versions. They skipped version 2.2.0 since it has a segfault bug source.

TURBOLINKS 3

For the folks who don’t like to meddle around with JS, Turbolinks offers an instantaneous performance boost, and allows you to retain most of your page and selectively update certain regions through partials. This is very similar to how SPA’s work, and you can choose to do all this from the server.

ACTION CABLE

Many projects these days use WebSockets to push live updates to the client. While most client browsers(IE > 9, Chrome, Firefox, Safari) have started to support this, we still need a robust client on the server to manage the subscribers and send an update signal appropriately. This feature is available out of the box in some of the newer frameworks, like Phoenix for Erlang. However, the Rails community had to resort to third party implementations, like Pushr, to get this working.

Rails traditionally offers all the tools that one needs to build a great app out of the box. That’s one reason why it is so popular, especially among the startup community. The lack of WebSocket support was a reason for major discontent among the community. It looks like the Rails core team took note of this and came up with Action Cable.

As a Team of Ruby , Rails, Java,JS and CSS Developer we are Commited towards the trending technologies and simplifying developers and Clients Projects .

For any Information regarding Upgrading your Rails Application or building your ideas we welcome you to Our Community.

This post is created by Santosh Mohanty . You can contact him for any questions at santa.jyp@gmail.com or message him on his linkedIn profile .


How To Create Rest WebServices With GUICE And Jersey

This is a simple example of how to use Google Guice , with Jersey to create JAX-RS web services , which can be deployed to any servlet container like Tomcat , Jboss , GlassFish etc .


We will be creating a simple Transaction Service , which will Create , update , and query Transactions . For this example , we are not using any database but a simple hashmap to store it .


So , first of all lets have a look at our maven pom.xml file . I have added dependency for Guice(jersey-guice) which is a guice extension of jersey.

<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>com.javaroots</groupId>
 <artifactId>codeChallenge</artifactId>
 <version>1.0</version>
 <packaging>war</packaging>
 <name>Code Challenge</name>
 <description>Code Challenge Sample Prject</description>

 <dependencies>
  <dependency>
   <groupId>com.sun.jersey.contribs</groupId>
   <artifactId>jersey-guice</artifactId>
   <version>1.19</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-json</artifactId>
   <version>1.19</version>
  </dependency>

  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
  </dependency>
  <dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
   <version>1.9.5</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.1</version>
  </dependency>

 </dependencies>
 <build>
  <finalName>${artifactId}</finalName>
 </build>

</project>

Now we have DAO like this .
package com.javaroots.dao;

import java.util.List;

import com.javaroots.model.Transaction;

public interface TransferDAO {
 
 public void create(Transaction tr);
 public Transaction get(Long id) ;
 
}
package com.javaroots.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.google.inject.Singleton;
import com.javaroots.dao.TransferDAO;
import com.javaroots.model.Transaction;
@Singleton
public class TransferDAOMemoryImpl implements TransferDAO{

 private ReadWriteLock lock ;
 private Lock readLock ;
 private Lock writeLock ;
 private Map store ;
 
 public TransferDAOMemoryImpl()
 {
  lock = new ReentrantReadWriteLock();
  readLock = lock.readLock();
  writeLock = lock.writeLock();
  store = new HashMap();
 }
 
 public void create(Transaction t){
  if(t.getParent_id() !=null)
  {
   Transaction parent = get(t.getParent_id());
   if(parent == null)
    throw new RuntimeException(" Invalid parent id . id not exist in system");
  }
  writeLock.lock();
  try
  {
   store.put(t.getId(),t);
  }
  finally
  {
   writeLock.unlock();
  }
 }
 
 public Transaction get(Long id) {
  readLock.lock();
  try
  {
   return store.get(id);
  }
  finally
  {
   readLock.unlock();
  }
 }
}

Model Class :
package com.javaroots.model;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown=true)
public class Transaction {
 
 private Long id ;
 private Long parent_id ;
 private String type ;
 private Double amount ;
 
 public Transaction(){};
 
 public Transaction(Transaction t)
 {
  this.id = t.id ;
  this.parent_id = t.parent_id;
  this.type = t.type ;
  this.amount = t.amount ;
 }
 @JsonIgnore
 public Long getId() {
  return id;
 }
 @JsonIgnore
 public void setId(Long id) {
  this.id = id;
 }
 
 public Long getParent_id() {
  return parent_id;
 }

 public void setParent_id(Long parent_id) {
  this.parent_id = parent_id;
 }

 public String getType() {
  return type;
 }
 public void setType(String type) {
  this.type = type;
 }
 public Double getAmount() {
  return amount;
 }
 public void setAmount(Double amount) {
  this.amount = amount;
 }
 
 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((id == null) ? 0 : id.hashCode());
  return result;
 }
 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Transaction other = (Transaction) obj;
  if (id == null) {
   if (other.id != null)
    return false;
  } else if (!id.equals(other.id))
   return false;
  return true;
 }
 
}

Now following is our Rest Service class :
package com.javaroots.services.rest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.javaroots.dao.TransferDAO;
import com.javaroots.model.Transaction;

@Singleton
@Path("transactionservice/")
public class TransactionService {
 
 private TransferDAO transferDAO ;

 @Inject
 public TransactionService(TransferDAO transferDAO)
 {
  this.transferDAO =  transferDAO ;
 }
 
 @PUT
 @Path("transaction/{transaction_id}")
 @Consumes(MediaType.APPLICATION_JSON)
 @Produces(MediaType.APPLICATION_JSON)
 public Response createTransaction(@PathParam("transaction_id")Long transactionId , Transaction entity) {
  entity.setId(transactionId);
  transferDAO.create(entity);
  Map map = new HashMap();
  map.put("status","OK");
  return Response.status(Status.OK).entity(map).build();
 }
 
 @GET
 @Path("transaction/{transaction_id}")
 @Produces(MediaType.APPLICATION_JSON)
 public Response getByType(@PathParam("transaction_id")Long transactionId) {
  Transaction toRet = transferDAO.get(transactionId);
  return Response.status(Status.OK).entity(toRet).build();
 }
}

Now we bind this together using google Guice's ServletContextListener . To enable json support , you need to bind JacksonJsonProvider as well .
package com.javaroots.listeners;

import org.apache.log4j.Logger;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.servlet.GuiceServletContextListener;
import com.javaroots.dao.TransferDAO;
import com.javaroots.dao.impl.TransferDAOMemoryImpl;
import com.javaroots.exception.RestExceptionMapper;
import com.javaroots.services.rest.TransactionService;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;

public class AppInitilizer extends GuiceServletContextListener {

 Logger log = Logger.getLogger(AppInitilizer.class);
 @Override
 protected Injector getInjector() {
  
   return Guice.createInjector(new JerseyServletModule() {
             @Override
             protected void configureServlets() {
                 bind(TransferDAO.class).to(TransferDAOMemoryImpl.class);
                 serve("/*").with(GuiceContainer.class);
                 // Configuring Jersey via Guice:
                 bind(TransactionService.class);
                 bind(RestExceptionMapper.class);
                 bind(JacksonJsonProvider.class).in(Singleton.class);

             }
         }); 
 }
}

Now include this in web.xml .
<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 version="3.0">

 <filter>
  <filter-name>guiceFilter</filter-name>
  <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>guiceFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
  <listener>
        <listener-class>com.javaroots.listeners.AppInitilizer</listener-class>
    </listener>

</web-app>
Now you can access service at localhost:8080/{contextpath}/transactionservice

Post Comments And Suggestions !!!