Friday, July 27, 2012

QueueSender or MessageProducer? Which one I should choose?


QueueSender or MessageProducer?

Well the answer is: - MessageProducer. There is nothing new in QueueSender or TopicPublisher which is not available in MessageProducer. But converse is true. MessageProducer has few more features than QueueSender and TopicPublisher. Creating a MessageProducer provides the same features as creating a TopicPublisher. or QueueSender.

Also, there is an added benefit, if your code is sending messages to Queue as well as a Topic, you can dynamically pass destination to your MessageProducer creator and make the code consistent.

This analogy can be used with QueueSession and TopicSession objects. Using a generic Session is always recommended.

But don’t be panic if you have existing code with QueueSender and QueueReceiver, for futher development though, please use their parents J

Did you still have a doubt? Post a comment. I will try to answer it as soon as possible.


Friday, July 20, 2012

Converting CSV to XML With Camel Bindy


Converting CSV file to XML using Apache Camel.


Why Apache Camel?
Because Camel Rocks :). Camel has huge transformation libraries which makes code easier and simple to understand and execute. Also Camel is free. It’s an open-source tool with huge user base and nice support. 

What’s the Corporate Problem?
Converting CSV to XML is common problem across IT industry where CSV might be the input imported by user and Web-Service might be expecting XML formatted data to run the business logic. Here we will do this conversion in two steps, and both the steps are useful for applicable applications.
Step 1. Converting CSV file to POJO objects (Beans)
Step 2. Converting POJO list to XML using xstream (Open Source easy to use Jar file)
If you are just interested in POJO list, please stop at first step.

Can you run through any example?

Sure thing. Let’s consider we have Employee.csv file having data like below.
employeeId,firstName,lastName,role
23445,Ambarish,Deshpande,Java Lead
23411,Paul,Bulson,Team Member

First we need a bean (DTO) class to map CSV fields. Getters / Setters are optional here.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@CsvRecord(separator = ",", skipFirstLine = true)
public class EmployeeDTO implements Serializable{
@XmlAttribute
      @DataField(pos = 1)
      private int employeeId;
      @XmlAttribute
      @DataField(pos = 2)
      private String firstName;
      @XmlAttribute
      @DataField(pos = 3)
      private String lastName;
      @XmlAttribute
      @DataField(pos = 4)
      private String role;
}

Annotations?

All @XML* annotations are coming from javax.xml.bind.annotation.* package.
For @CSVRecord and @DataField you have import camel-bindy.jar. I have listed all the dependencies in Appendix section at last.

Now, for actual conversion, camel route must be created.

public class ConvertorRoute implements RoutesBuilder{
     
@Override
public void addRoutesToCamelContext(CamelContext context) throws Exception {
  context.addRoutes(new RouteBuilder() {
public void configure() {
  try {
            DataFormat bindy = new BindyCsvDataFormat("com.package.dto");
                  from("file://TEST?fileName=Employee.csv").
                  unmarshal(bindy).
                  marshal().
                  xstream().
                  to("file://TESTOUT?fileName=employee.xml");
            } catch (Exception e) {
                        e.printStackTrace();
            }
         }
     });
}

public static void main(String[] args) { 
 try{
CamelContext context = new DefaultCamelContext();
      ConvertorRoute route = new ConvertorRoute();
      route.addRoutesToCamelContext(context);
      context.start();
      Thread.sleep(5000);
      context.stop();
  }catch(Exception exe){
      exe.printStackTrace();
}

}

Steps in Route:

1.    Register Bean package (where DTO class resides) with BindyCSVDataFormat.

    DataFormat bindy = new BindyCsvDataFormat("com.package.dto");

2.    Pick Up the file from TEST folder. (Root//TEST)
3.    Unmarshal the csv file with register Bindy. This step creates a List of EmployeeDTO. If intended output is achieved here. Please use this output further.
4.    Marshal().xstream() will convert this DTO List to XML and finally
5.    Output file will be written on TESTOUT folder as employee.xml file.


Employee.XML file:             


<?xml version="1.0" ?>
<list>
<map>
<entry>
  <string>com.thd.eai.dto.EmployeeDTO</string>
<com.thd.eai.dto.EmployeeDTO>
      <employeeId>23445</employeeId>
    <firstName>Ambarish</firstName>
      <lastName>Deshpande</lastName>
      <role>Lead Java</role>
   </com.thd.eai.dto.EmployeeDTO>
  </entry>
 </map>
<map>
 <entry>
  <string>com.thd.eai.dto.EmployeeDTO</string>
<com.thd.eai.dto.EmployeeDTO>
      <employeeId>23411</employeeId>
      <firstName>Paul</firstName>
      <lastName>Bulson</lastName>
      <role>Team Member</role>
   </com.thd.eai.dto.EmployeeDTO>
 </entry>
</map>
</list>



Appendix and References:

List of dependencies: 

camel-bindy-2.9.0.jar,
camel-core-2.9.0.jar,
camel-csv-2.9.0.jar,
camel-xstream-2.9.0.jar, 
slf4j-api-1.6.4.jar,
slf4j-log4j12-1.6.4.jar,
solr-commons-csv-1.3.0.jar,
xstream-1.3.1 

Important Links: