Showing posts with label camel. Show all posts
Showing posts with label camel. Show all posts

Thursday, October 29, 2015

MDB (Message Driven Beans) Vs. SpringJMS - Point by Point Comparison

EJB’s Message Driven Beans (MDB) Vs. SpringJMS
MDB and SpringJMS can be compared with multiple features:

1.       Learning Curve

Most important feature of SpringJMS is, object can be easily configured in XML format making is extra easy to manage.  Some features like concurrentConsumer can be managed with XML without touching Java code.

MDB on the other hand involves expert level understanding of EJB and has more LOC to write for same operation.  So Overall learning Curve for SpringJMS is less.

2.       Development Time
Spring implementation uses the JmsTemplate helper class to simplify working with the JMS API to send the message. Also, auto starting consumers with application context and ease of handling properties with xml configuration, reduces development time, in turn production cost of application.
MDB though robust, needs good amount of efforts in comparison.

3.       Container Dependency
MDB requires EJB container. Container is mainly responsible for instantiation and handling other life cycle events for MDB. EJB 3.0 also has additional packaging and deployment requirements that
Spring does not. Also message listeners must be EJB components.

Spring is container of its own. SpringJMS do not require any external container to execute. Any POJO can potentially be activated in response to incoming messages

4.       Multi-Queue Configuration:
MDBs are static for one queue. One MDB cannot be used for consuming from two or multiple queues. On the contrary, Spring provides the flexibility to customize the number of queues to listen to and dynamically configure the destinations as well.

5.       Security
For MDB, security is managed by the EJB container by configuring a security identity for the MBM

Spring UserCredentialsConnectionFactoryAdapter provides a mechanism to specify user credentials for every JMS connection to secure the JMS connection.

6.       Dependency management/configurability/intermediation
Spring offers much more mature and configurable support for dependency management than EJB 3.0 with its dependency injection and IOC framework

7.       Availability
The Enterprise server controls JMS connection pooling and failover and reconnecting to the message broker when the connection is lost has to be supported and configured at the enterprise server level .

Individual applications and modules cannot control or override JMS availability
Spring DMLC automatically re-establishes connections if the message broker becomes unavailable

8.       Performance

The EJB MDB container manages the JMS Connection Pool and needs to be configured to optimize the concurrent processing of messages

Spring DMLC allows you to scale the number message consumers using the concurrentConsumers property and the maxConcurrentConsumers property. It provides various levels of caching of the JMS resources (connections and sessions) and JMS consumers for increased performance

9.       Transaction

Can use the default container managed transaction to allow the EJB container to handle transaction demarcation or specify local transactions to group message sends and receives

Spring DMLC provides support for local JMS transactions as well as an external transaction manager around message reception and listener execution

10.   Message Convertors

Spring provides message converters which can automate the conversion of Java objects to message content

MDB provides no such features.

11.   Future Orientation

Spring has vibrant open source community and considered as very stable but futuristic design. Many newer MOMs and EIPs (Enterprise Integration Pattern) like Camel directly uses Spring for messaging implementation.

EJBs on the contrary and seen lesser in market.

Summary:

                Considering current era of IT development, adopting SpringJMS over MDB is always a better choice. 

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:

Tuesday, May 15, 2012

CSV to XML transformation using Camel

Lots of Projects I know needs this transformation.
CSV to XML, where you might be reading user uploaded CSV file or it can be Pipe delimited flat file and make a XML out of it.
Below is the code doing this using camel and Xstream. I am exploring more to get XML nodes to populate as headers, but not yet successful. I will update that as soon as I get the solution. till then.. this is the good code u can use.

 

package com.XYZ;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class FileCSVtoXMLConversion {
private static XStream xStream;
public static void main(String args[]) throws Exception {
// create CamelContext
CamelContext context = new DefaultCamelContext();
xStream = new XStream(new DomDriver());
// add our route to the CamelContext
context.addRoutes(new RouteBuilder() {
public void configure() {
from("
file://Some/TEST?fileName=ArticleTest.csv").
unmarshal().
csv().
process(new Processor() {
  @Override
  public void process(Exchange exchange) throws Exception {
    String xmlConverted = xStream.toXML(exchange.getIn().getBody());
    exchange.getIn().setBody(xmlConverted);
  }
 }
).to("
file://Some/TESTOUT?fileName=ArticleTest.XML");
}
});
// start the route and let it do its work
context.start();
Thread.sleep(10000);
// stop the CamelContext
context.stop();
}
}