Sending a Tweet Using Apache Camel


Twitter is an online news and social networking service where users post and interact with messages.

POC on sending a tweet from java application using Apache camel API

Technologies used in this POC are :
1. JDK 1.7
2. Apache Camel 2.12.x
3. Maven.

Lets create a maven project.

open pom.xml add the below dependencies


 <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.learning</groupId>  
      <artifactId>tweetingthroughapachecamel</artifactId>  
      <version>0.0.1-SNAPSHOT</version>  
      <dependencies>  
           <dependency>  
                <groupId>org.apache.camel</groupId>  
                <artifactId>camel-core</artifactId>  
                <version>2.12.0</version>  
           </dependency>  
           <dependency>  
                <groupId>org.apache.camel</groupId>  
                <artifactId>camel-twitter</artifactId>  
                <version>2.12.0</version>  
           </dependency>  
      </dependencies>  
 </project>  

Generate the ConsumerSecret,ConsumerKey,AccessToken and AccesstokenSecret from https://apps.twitter.com/

Now lets create a RouteBuilder JavatoTwitterRouteBuilder.java class

 package com.learning.apachecamel.twitter;  
 import org.apache.camel.builder.RouteBuilder;  
 public class JavatoTwitterRouteBuilder extends RouteBuilder {  
      @Override  
      public void configure() throws Exception {  
           // Generate the ConsumerSecret,ConsumerKey,AccessToken and  
           // AccesstokenSecret from https://apps.twitter.com/  
           from("direct:sendingtweet").to(  
                     "twitter://timeline/user?consumerKey=XYZ&consumerSecret=ZYZ&accessToken=ZYZ&accessTokenSecret=MAY");  
      }  
 }  
Lets create one more class to test the routes.


 package com.learning.apachecamel.twitter;  
 import org.apache.camel.CamelContext;  
 import org.apache.camel.ProducerTemplate;  
 import org.apache.camel.impl.DefaultCamelContext;  
 public class JavaTwittingClass {  
      public static void main(String[] args) {  
           CamelContext camelContext = new DefaultCamelContext();  
           try {  
                camelContext.addRoutes(new JavatoTwitterRouteBuilder());  
                ProducerTemplate producerTemplate=camelContext.createProducerTemplate();  
                camelContext.start();  
                producerTemplate.sendBody("direct:sendingtweet","This tweet is done from Java Application");  
                System.out.println("Message sent");  
           } catch (Exception e) {  
                System.err.println("Message not sent");  
                e.printStackTrace();  
           }  
      }  
 }  


Output:
   
 SLF4J: Defaulting to no-operation (NOP) logger implementation  
 SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.  
 Message sent  


Unmarshalling XML to Java (JAXB)

Unmarshalling XML to Java (JAXB)
JAXB : Stands for Java Architecture for XML binding. This framework helps us to convert Xml data to java content and Vice versa.

JaxB mainly uses two terminologies,
1. Unmarshalling : Reading Xml to Java content.
2. Marshalling : Writing Java Content to Xml

POC on UnMarshalling a sample XML file usercredentials.xml to Java Objects as below 

 <?xml version="1.0" encoding="UTF-8"?>  
 <config>  
      <Users>  
           <user>  
                <username>ABC</username>  
                <password>ABC@123</password>  
           </user>  
           <user>  
                <username>BBC</username>  
                <password>BBC@123</password>  
           </user>  
           <user>  
                <username>CBC</username>  
                <password>CBC@123</password>  
           </user>  
      </Users>  
 </config>  


Technologies used in this POC:

1. JDK 1.7
2. Maven 3.X
3. XSD 
4. XML 
5. JAXB 
6. Eclipse IDE


Create a new maven Project  in eclipse.

Open the pom.xml add the dependencies and plugin as below.

 <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.learning</groupId>  
      <artifactId>jaxbunmarshalling</artifactId>  
      <version>0.0.1-SNAPSHOT</version>  
      <dependencies>  
           <dependency>  
                <groupId>commons-configuration</groupId>  
                <artifactId>commons-configuration</artifactId>  
                <version>1.6</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.xml.bind</groupId>  
                <artifactId>jaxb-api</artifactId>  
                <version>2.2.6</version>  
           </dependency>  
      </dependencies>  
      <build>  
           <plugins>  
                <!-- JAXB xjc plugin that invokes the xjc compiler to compile XML schema   
                     into Java classes. -->  
                <plugin>  
                     <groupId>org.codehaus.mojo</groupId>  
                     <artifactId>jaxb2-maven-plugin</artifactId>  
                     <version>1.5</version>  
                     <executions>  
                          <execution>  
                               <goals>  
                                    <goal>xjc</goal>  
                               </goals>  
                          </execution>  
                     </executions>  
                     <configuration>  
                          <schemaDirectory>${basedir}/src/main/resources/schema</schemaDirectory>  
                          <packageName>com.learning.usercredentials</packageName>  
                          <outputDirectory>${basedir}/src/main/java</outputDirectory>  
                          <removeOldOutput>false</removeOldOutput>  
                          <clearOutputDir>false</clearOutputDir>  
                          <forceRegenerate>true</forceRegenerate>  
                     </configuration>  
                </plugin>  
           </plugins>  
      </build>  
 </project>  
Now lets create an XSD usercredentials.xsd for XML
 xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">  
  <xs:element name="config">  
   <xs:complexType>  
    <xs:sequence>  
     <xs:element name="Users">  
      <xs:complexType>  
       <xs:sequence>  
        <xs:element name="user" maxOccurs="unbounded" minOccurs="0">  
         <xs:complexType>  
          <xs:sequence>  
           <xs:element type="xs:string" name="username"/>  
           <xs:element type="xs:string" name="password"/>  
          </xs:sequence>  
         </xs:complexType>  
        </xs:element>  
       </xs:sequence>  
      </xs:complexType>  
     </xs:element>  
    </xs:sequence>  
   </xs:complexType>  
  </xs:element>  
 </xs:schema>  

Create a folder called schema (not necessarily required) under src\main\resources of the project. and place the xsd file in the schema folder.


 
It generates XML bind classes from the XSD. We are using XSD in this Project because, so that strict structure of XML followed. even if there is a mismatch in the tag, XML will not be loaded.

Lets create a singleton class UnMarshallXmlToJava.java

 package com.learning.user.unmarshal;  
 import java.io.File;  
 import java.util.HashMap;  
 import java.util.List;  
 import java.util.Map;  
 import javax.xml.bind.JAXBContext;  
 import javax.xml.bind.JAXBException;  
 import javax.xml.bind.Unmarshaller;  
 import com.learning.usercredentials.Config;  
 import com.learning.usercredentials.Config.Users.User;  
 public class UnMarshallXmlToJava {  
      /*  
       * Reason for SingletonClass is, Keep on generating java contents of XML  
       * data is a memory overhead, so use it only required. So we load the XML  
       * data and exposing to the outside world through a method.  
       *   
       */  
      private static UnMarshallXmlToJava unMarshall = null;  
      private static Config config = null;  
      private UnMarshallXmlToJava() {  
           // Providing location of the xml file to file Object  
           try {  
                File xmlfile = new File(  
                          "src/main/resources/usercredentials.xml");  
                JAXBContext context = JAXBContext.newInstance("com.learning.usercredentials");  
                // creating an Unsmarshaller instance.  
                Unmarshaller unmarshaller = context.createUnmarshaller();  
                // loading the file object to the unmarshaller, and return type is  
                // typecasted to Config Class, by this Xml data is converted to java  
                // objects  
                config = (Config) unmarshaller.unmarshal(xmlfile);  
           } catch (JAXBException e) {  
                e.printStackTrace();  
           }  
      }  
      public static UnMarshallXmlToJava getInstance() {  
           if (unMarshall == null) {  
                unMarshall = new UnMarshallXmlToJava();  
                return unMarshall;  
           }  
           return null;  
      }  
      // returning the coverted XML to java content as a map.  
      public Map<String, String> getUserCredentials() {  
           Map<String, String> map = new HashMap<String, String>();  
           List<User> userList = config.getUsers().getUser();  
           for (User user : userList) {  
                map.put(user.getUsername(), user.getPassword());  
           }  
           return map;  
      }  
 }  

Lets create one more class TestingUnMarshaling.java to test the code.

 package com.learning.user.unmarshal;  
 import java.util.Map;  
 import java.util.Map.Entry;  
 public class TestingUnMarshaling {  
      public static void main(String[] args) {  
           Map<String, String> usersMap = UnMarshallXmlToJava.getInstance().getUserCredentials();  
           for (Entry<String, String> userEntry : usersMap.entrySet()) {  
                System.out.println("*********************************");  
                System.out.println("UserName : " + userEntry.getKey());  
                System.out.println("Password : " + userEntry.getValue());  
                System.out.println("*********************************");  
           }  
      }  
 }  

Output:

 *********************************  
 UserName : ABC  
 Password : ABC@123  
 *********************************  
 *********************************  
 UserName : BBC  
 Password : BBC@123  
 *********************************  
 *********************************  
 UserName : CBC  
 Password : CBC@123  
 *********************************