Friday 30 July 2021

Scala Exception handling best practices

It's very good to be an optimistic person in real life however while programming you need to be a little pessimist to handle a situation where your code does not work as per expectation due to some problem which has nothing to do with your code or some time because of missing some corner cases while coding.  

So how do Exceptions helps us? By providing us following information in case of failure :
  • What went wrong? (exception.getMessage)
  • Where did it go wrong? (exception.getStackTrace)
  • Why it went wrong? (exception.getCause)
So in this post, I will try to cover two scenarios:
  1. How Scala signals something went wrong (Exceptions)
  2. Various ways of handling Exception cases
Before going into implementation details, I would like to throw light on some facts about Exceptions handling in Scala :
  • Scala does not have concept of Checked and Un-Checked Exceptions
  • Scala does not allow you to put throws clause in method signature as it does not differentiate between Checked and Un-Checked Exceptions.
  • You can achieve throws functionality using @throws annotation. eg. @throws(classOf[IOException]). However, this won't force Scala caller method to handle thrown Exception. This will only force Java caller method to handle that Exception.
  • Scala supports Java way of Exception handling ie. try-catch. However not recommended way in Scala.
  • Scala treats Exceptions as Case classes so you can apply Pattern matching on exceptions so you can handle all Exceptions in a single catch block.
  • Catching Throwable in Scala is deadlier than doing same in Java.
Scala supports following ways of handling Exceptions :
  1. try-catch
  2. Try
  3. Either[Left, Right]
  4. Scala Futures comes with support for exception handling
Let's look at these option in detail one by one :

1. try-catch

  • This is a non-functional way of handling exceptions. 
  • This is supported by Scala to provide backward compatibility with Java (This is my opinion :) )
  • Scala supports pattern matching on all Exception classes. So you can handle all exceptions in one catch block
  • Makes your code look ugly (Again my opinion)
  • Though Scala support try-catch block you should keep this option as last option to handle exceptions in Scala.

  def divide(number: Int, divider: Int): Int = number/divider

  def callDivide(): Option[Int] = {
    try {
      Option(divide(3, 0))
    } catch {
      case e: ArithmeticException => None
      case e: Exception => throw new Exception("Something went wrong.")
    }
  }

2. Try

  • Try provides you functional way to wrap your Exception prone code to handle Exceptions
  • It was originally written by Twitter developers and ported in Scala API's in Scala version 2.10 and also ported in version 2.9.3
  • You can imagine it as similar to Option or Either
  • This is monad which will result either in : 
  1. Success - In case of successful execution of code
  2. Failure - In case of error. Failure will wrap Throwable and return it to caller. 
  • One of the most important benefits of using Try is, it supports all higher-order functions (chaining operations) like map, flatmap, foreach etc. 

def divide(number: Int, divider: Int): Try[Int] = Try(number/divider)

def callDivide(): Int = {
    divide(4, 0) match {
      case Success(result) => result
      case Failure(e) => println("Exception occurred" + e.getMessage); 0
    }
  }

Sunday 3 July 2016

Java SOAP Web Services MCQ's for Interview and WS Certification Exam 1Z0-897

1) Which of the following transport protocols are complient with SOAP
A. HTTP
B. SMTP
C. FTP
D. TCP
E. All of the above
Ans - E

2) Select HTTP methods associate with SOAP Web service.
A. Put
B. Post
C. Get
D. Delete
Ans - B 
Desc - SOAP only uses POST method for HTTP communication.

3) Select Web Service technology stack from following options (any 3)
A. SOAP
B. JSON
C. JAX-RS
D. WSDL
E. UDDI
Ans - ADE

4) Select correct definition of a WSDL's <service> element.

A. Collection of related endpoints.

B. Contains data type definitions using type system.

C. A single endpoint defined as a combination of a binding and a network address.
D. Set of operations supported by one or more Endpoints.
Ans - A

5) Select the operations supported by Web Services.

A. One way (Request only)

B. Two way (Request - Response)

C. Solicit-Response (Server pust message and client responds)
D. Notification (Request/push message from server to client)
E. All of the above
Ans - E

6) Select statements which are true for SOAP. (any 3)
A. SOAP Transport protocol used by Web Services
B. SOAP is specification for exchanging structured information
C. SOAP relies on other trasport protocols like http, ftp for data trasmission 
D. SOAP uses xml to format data
E. SOAP uses json to format data
Ans - BCD

7) You are going to develop Stock market web service which will be consumed by other companies. Jave team from your company want to re-use your web service code as soon as possible. Which approach you will follow in this case?
A. Top down (contract first)
B. Meet in the middle
C. Bottom up (code first)
D. None of the above
Ans - C
Desc - In bottom up approach you start with writing service code so code will be available earliest for other teams using this approach.

8) Our company wants to create JAX-WS Web service client for weather forcast service. This weather forcast service is implemented in C++. You have given a WSDL file for service. What is correct statement to be able to create WS client from WSDL. (Select one).
A. Use JAXP to parse and generate the java classes from WSDL. Then create Service Endpoint Interface(SEI) from factory classes. Then use SEI to call WS.
B. Use wsgen to generate SEI from WSDL and then invoke SEI's methods to call WS.
C. Use wsimport to generate SEI from WSDL and then invoke SEI's methods to call WS.
D. We can not consume a web service created in C++ on java.
Ans - C
Desc - To create WS client from WSDL we use wsimport tool. Wsgen is used to create web service from WSDL.

9) Our company want to create application in which servlet will be exposed as WS endpoint. What we will require among following? (any 3)
A. Application needs to be packaged as JAR file.
B. Application needs to be packaged as WAR file.
C. web.xml is required.
D. webservice.xml is required.
E. WEB-INF directory is required.
F. META-INF directory is required.
Ans - BCE
Desc - We need to package application as WAR file to deploy in web container. We need WEB-INF/web.xml file inside WAR file.

10) Our company has created web service for employee payroll system which is deployed in Web container. Now we have new requirements from management to protect access to this service URL using basic authentication. Which file we need to modify to fulfill this requirement?
A. security.xml
B. sun-web.xml
C. web.xml
D. webservices.xml
Ans - C
Desc - We have to update web.xml with security configurations for URLS. This is xml element we need to add in web.xml <auth-method>basic</auth-method>

11) Select the feature provided by EJB endpoint exposed as a web service. (any 3)
A. Client Managed Transactions
B. Java EE declarative Security
C. Java EE programatic Security
D. HTTP Sessions
E. Container Managed transactions.
Ans - ACE
Desc - Exposing EJB bean as WS endpoint we can use declarative security using EJB annotation, programmatic security and EJB container managed transactions.


12) We have created one web service which is deployed in web container, now we need to support WS client session in our service. However we have to expire a session in case user session is inactive for 10 mins. Which file we need to  modify for this requirement.
A. security.xml
B. sun-web.xml
C. web.xml
D. webservices.xml
Ans - C
Desc - We need to add <session-config><session-timeout>10</session-timeout></session-config> in web.xml file.

13) What is the correct web.xml-snippet to declare a session time-out of 3 minutes in web.xml?
A. <session-config>    <session-timeout>3</session-timeout> </session-config>
B. <session-config>    <session-timeout>180</session-timeout> </session-config>
C. <session-timeout>    <session-time>3</session-time> </session-timeout>
D. <session-timeout>    <session-time>180</session-time> </session-timeout>
Ans - A

14) Select programming languages supported by Web Services
A. c++
B. Java
C. Python
D. C
E. All of the above
Ans - E

15) What is an best way of the handling of application exceptions thrown by a
JAX-WS service endpoint?
A. Exceptions should be mapped to faults in WSDL.
B. Exceptions are NOT handled by JAX-WS clients.
C. Exceptions are always propagated to JAX-WS clients as RemoteExceptions.
D. Exceptions are always propagated to JAX-WS clients as WebServiceExceptions.
E. Exceptions are always propagated to JAX-WS clients as SOAPFaultExceptions.
Ans - A

20) What is the correct definition of WSDL's port element?
A. Contains data type definitions using type system.
B. Description of an action supported by the service.
C. Set of operations supported by one or more Endpoints.
D. A single endpoint defined as a combination of a binding and a network address.
Ans - D
Desc - PortType element contains supported binding, literals by endpoint and networ address of endpoint.

21) Select one of the use of javax.xml.ws.BindingProvider interface while working with JAX-WS.
A. Set custom Hadlers chain
B. Set UserName and Password used for BASIC Authentication
C. Validate SOAP request message against xml schema
D. Validate SOAP response message against xml schema

22) We have configured a number of Handlers in our Web Service. This is the order of the handlers in the configuration file:
1. LogicalHandler 1
2. LogicalHandler 2
3. SOAPHandler 1
4. SOAPHandler 2

What will be the order of execution on an outbound message?
A. LogicalHandler 1 - SOAPHandler 1 - LogicalHandler 2 - SOAPHandler 2
B. SOAPHandler 1 - SOAPHandler 2 - LogicalHandler 1 - LogicalHandler 2
C. LogicalHandler 1 - LogicalHandler 2 - SOAPHandler 1 - SOAPHandler 2
D. SOAPHandler 2 - SOAPHandler 1 - LogicalHandler 2 - LogicalHandler 1
E. None of above.
Ans - C
Desc - For outgoing message first logical handlers gets executed then SOAPHandlers. And reverse for Inbound message.

23) Please select incorrect statement among following statements.
A. Confidentiality - encrypting of SOAP messages
B. Integrity - signing of SOAP messages
C. Authentication - attach security tokens to SOAP messages
D. Non-repudiation - signing of SOAP messages
E. Authorization - attach identity tokens to SOAP message
Ans - E

24) Which two statements are true about the Web services? (any 2)
A. SOAP messages are compressed during transport to reduce size of payload.
B. You have to implement session tracking via HTTP cookies.
C. The WSDL defines services as collections of network endpoints.
D. All data shared between Java and non-Java components must be in XML format.
E. Data interchange is doen via in XML.
Ans - CE

25) We have a Web Service that can respond with a Street name when receiving a House number. This service will be used on several mobile devices and size of payload should be small to consume less bandwidth. Which technologies can provide the best solution for this requirement. (any 3)
A. XML
B. JSON
C. JAX-WS
D. JAX-RS
E. HTTP
Ans - BDE

26) What are three benefits of using SSL to connect to a Web service without mutual
authentication. (any 3)
A. The server is assured of the client's identity if the client issues the certificate.
B. The client is assured of the server's identity.
C. Message integrity is preserved between the client and the server.
D. The communication between the client and the server is still logged.
E. The communication between the client and the server is encrypted.
F. Using SSL over HTTP incurs less overhead than HTTPS.
Ans - ACE

27) We want to develop a Web Service and after developing we understood result processing can take a long time to finish. So we decided to convert it to asynchronous method invocations. What steps we need to perform to convert our synchronous Web Service to an asynchronous Web Service? (any 2)
A. An asynchronous transport protocol to facilitate the asynchronous invocations.
B. The client providing a ReplyTo-address for the response.
D. A correlation identifier in order to relate the request and response.
E. The client providing a From-address in order for the Web Service to facilitate asynchronous processing.
Ans - BD

28) Given a following code snippet of the service can you tell what is the name of the operation in WSDL file?

@WebService(serviceName = ""PayrollSystemService"", name = ""PayrollSystem"", portName = ""PayrollSystemPort"")
public class PayrollSystem {

 public String getEmployeeDetails(Long empId) {
  return ""dummyDetails"";
 }
}

A. getEmployeeDetails
B. getEmployeeDetailsOperation
C. getEmployeeDetailsMethod
D. getEmployeeDetailsWebMethod
E. getEmployeeDetailsService
Ans - A
Desc - Default value of the operation name is the name of the method. You can modify the name of the operation using @WebMethod annotation.

29) What is the correct WSDL generated from this Web Service declaration: 
@WebService (name=""TaxiService"", portName=""TaxiPort"", serviceName=""TaxiWebService"") public class TaxiServiceImpl {    public void taxi(String msg) {       
 System.out.println(msg);
 } 
}

  A.  <definitions> . . .
    <portType name=""TaxiWebService""> . . .</portType>
    <binding name=""TaxiPortBinding"" type=""...""> . . . </binding>
    <service name=""TaxiServiceImplService"">
     <port name=""TaxiPort"" binding=""tns:TaxiPortBinding"">  . . . </port>
    </service>
   </definitions>
 
  B. <definitions> . . .
    <portType name=""TaxiService""> . . .</portType>
    <binding name=""TaxiPortPortBinding"" type=""...""> . . . </binding>
    <service name=""TaxiWebService"">
     <port name=""TaxiPortPort"" binding=""tns:TaxiPortPortBinding"">  . . . </port>
    </service>
   </definitions>
 
  C.  <definitions>
    . . .
    <portType name=""TaxiService""> . . .</portType>
    <binding name=""TaxiServiceImplPortBinding"" type=""...""> . . . </binding>
    <service name=""TaxiServiceImplService"">
     <port name=""TaxiServicePort"" binding=""tns:TaxiServiceImplPortBinding"">  . . . </port>
    </service>
   </definitions>
 
  D.  <definitions>
    . . .
    <portType name=""TaxiService""> . . .</portType>
    <binding name=""TaxiPortBinding"" type=""...""> . . . </binding>
    <service name=""TaxiWebService"">
     <port name=""TaxiPort"" binding=""tns:TaxiPortBinding"">  . . . </port>
    </service>

   </definitions>
Ans - D

30) Which of the following code snippet matches to this WSDL portType element?  
<portType name=""ElementsTableImpl"">
 <operation name=""getTable"">
  <input message=""tns:getTable"" />
  <output message=""tns:getTableResponse"" />
  <fault message=""tns:WsException"" name=""WsException"" />
 </operation>
</portType>

  A. @WebService
   public class ElementsTableImpl {   
    public SimpleElementsTable getElementsTable(Integer number) throws WsException {       
     SimpleElementsTable table = new SimpleElementsTable(number);
         return table;   
    } 
   }

  B. @WebService
   public class ElementsTableImpl {    
    public SimpleElementsTable getTable(Integer number) {       
     SimpleElementsTable table = new SimpleElementsTable(number);       
     return table;    
    }
   }
   
  C. @WebService (endpointInterface=""ElementsTableService"")
   public class ElementsTableImpl {   
    public SimpleElementsTable getTable(Integer number) throws WsException {       
     SimpleElementsTable table = new SimpleElementsTable(number);       
     return table;    
    } 
   }

  D. @WebService
   public class ElementsTableImpl {    
    public SimpleElementsTable getTable(Integer number) throws WsException {       
     SimpleElementsTable table = new SimpleElementsTable(number);       
     return table;    
    }
   }
Ans - D

Please feel free to correct me if I am wrong anywhere.


Clearing Java EE 6 Web Services Developer Certified Expert 1Z0-897

Recently I cleared Java EE 6 Web Services Developer Certified Expert exam. I cleared this exam after few months of preparations. Preparation took around 3 to 4 months. If you have prior experience in SOAP and Rest web services then 3 to 4 months is enough time. And If you do not have prior working experience then I would suggest to add few more moths.

Exam overview.

  • Duration of exam - 90 Minutes 
  • No. of questions  - 55
  • Passing Score     - 65%
  • Questions format - MCQ's

     Here are some of the books and resources which I referred while preparing for this Exam.

  1. Mikalai Zaikin's study guide - This is one of the best resource you can find.
  2. Ivan Krizsan's study notes's - These notes doesn't cover all the topics of the exam but whichever topics are covered are very nicely explained. I would suggest to start with these notes as they cover from very basics of XML's.
  3. Java Web Services: Up and Running - This book is one of the must read for this exam. If you have enough time then I would suggest to read both 1st and 2nd edition.
  4. Developing Java Web Services - This is not very popular book however I found this book very helpful. Many complicated topics are very nicely explained in this book. 
  5. Mikalai Zaikins Quiz - Once you think you read enough, this quiz is good to tell you that you need to read lot more :).
  6. List of exam topics from Oracle.
So for me these were enough to clear this exam. There are many more resources and mock exam test available for this exam.

     Note - This exam is not as easy as SCJP (now OCJP) exam. The main reason is because there is no book available which you can consider as a bible for this exam just like SCJP Study Guid by Kathy Sierra and Bert Bates for SCJP exam.

Once you clear this exam this is what you earn along with knowledge.



All the best :)

Thursday 9 June 2016

How to Configure and Use Apache Camel with Spring

 1. Overview


This article will help you to configure and use Apache Camel with Spring Framework.

Apache Camel implements Enterprise Integration Patters.  If you want to explore EIP concept in detail, you can read this book written by Gregor Hohpe and and Bobby Woolf, who conceptualize the Enterprise Integration Patters.
Apache Camel provides many useful components like JPAHibernateFTPApache-CXFApache CXF-REST,  AWS-S3 and many more. Basically these components are useful in integrating data between two different systems. For eg. Pull data from database and send it to another system over REST API calls.


In this tutorial, for simplicity purpose we will use Apache Camel's File component and Apache Camel version 2.16.1 with Spring version 4.2.4.RELEASE.

We will use Apache Camel to perform following task:
  • Read file from source directory.
  • Convert file content to UpperCase using custom Processor.
  • Write converted output to destination directory.
  • Convert file content to LowerCase using Camel Translator Feature.
  • Write converted output to destination directory.
We will follow these steps to develop and run this application:
  • Create Project skeleton using maven.
  • Add Apache Camel dependencies to pom file.
  • Create Camel Context file.
  • Define Camel Route for converting file content to UpperCase using custom processor.
  • Update Camel Route for converting file content to LowerCase using Camel's Message Translator.
  • Create ApplicationRunner class with main method to load and run Camel Context.
  • Create input and output directories.
  • Build application and run Camel Context.

2. Create Maven Project


Let's start with generating project artifacts using maven command. Run following command to generate project skeleton.
mvn archetype:generate -DgroupId=org.apache.camel -DartifactId=ApacheCamelFileProcessor -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Once this command is runs successfully, you can see generated project directory ApacheCamelFileProcessor.

3. Add Maven Dependencies


Add following dependencies to to ApacheCamelFileProcessor/pom.xml file.

<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/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.apache.camel</groupId>
 <artifactId>ApacheCamelFileProcessor</artifactId>
 <packaging>jar</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>ApacheCamelFileProcessor</name>
 <url>http://maven.apache.org</url>
 <properties>
  <env.camel.version>2.16.1</env.camel.version>
  <env.spring.version>4.2.4.RELEASE</env.spring.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-core</artifactId>
   <version>${env.camel.version}</version>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-spring</artifactId>
   <version>${env.camel.version}</version>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-stream</artifactId>
   <version>${env.camel.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${env.spring.version}</version>
  </dependency>
 </dependencies>
</project>


Once pom file is updated with these dependencies  you need to run following maven build command to download jar files.

mvn clean install

4. Camel Context file


Create Spring Context file where we will define Camel Routes later. Create file ApacheCamelFileProcessor/src/main/resources/camel-context.xml. This is content to your context file with all required Apache Camel and Spring namespaces and schema locations.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
  http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

 <camelContext xmlns="http://camel.apache.org/schema/spring">
        <!-- Add routes here -->
 </camelContext>

</beans>

This <camelContext> element represents Camel Context which we can compare with Spring Application Context. Now your context file is ready to start defining Camel Routes.

5. Camel Route file.


Now we will write our first route to convert file content to UpperCase.
We need to define source from where route will read data, which can be database, file, console etc. In our case it will be file. eg. <from uri="file:input_directory_location" />
Then we need to define the processor of the data read from source. We are going to write custom processor class in our case. This custom processor class will be a spring bean which will implement standard Camel Processor Interface. eg. <process ref="customProcessorbeanId" />
Once data is processed we need to tell route to where to store the processed data which can again be anything like database, file or display on console. In our case we are going to store it in file. eg. <to uri="file:output_directory_location" />
This is how your your camel-context.xml file will look like with route.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
  http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

 <camelContext xmlns="http://camel.apache.org/schema/spring">
  
  <route customId="true" id="rout1">
   <!-- Read files from input directory -->
   <from uri="file://data/input" />
   <!-- Transform content to UpperCase -->
   <process ref="myFileProcessor" />
   <!-- Write converted file content -->
   <to uri="file://data/outputUppperCase" />
  </route>
 
 </camelContext>
 <bean id="myFileProcessor" class="org.apache.camel.processor.FileProcessor" />
</beans>

We need to create those directories mentioned in URI's and put some files in input directory. We will create them before running application.

5.1. Create Custom Processor


Create class org.apache.camel.processor.FileProcessor which is mentioned in camel-context.xml file as bean.
Now implement org.apache.camel.Processor interface which is standard processor interface provided by Apache Camel. After implementing this interface we need to define its process(Exchange exchange) method. This Exchange object holds all details of data read from source.
Then we need to read content of the message (file content in our case) and do processing on that content. Once processing is completed we will set the new content to Exchange object.
This is the Custom Processor for reading the file content and converting it to UpperCase and setting it on Exchange object.
package org.apache.camel.processor;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class FileProcessor implements Processor {

 public void process(Exchange exchange) throws Exception {
  //Read file content
  String originalFileContent = (String)exchange.getIn().getBody(String.class);
  
  //Convert file content to upper case.
  String upperCaseFileContent = originalFileContent.toUpperCase();
  
  //Update file content.
  exchange.getIn().setBody(upperCaseFileContent);
 }

}
This process method will get executed for every input received from source.

6. Update Camel Route for converting content to lowercase.


We will update Camel route to convert same file content to lowerCase. However for converting data to lowerCase we will not create custom processor. Instead we will use Apache Camel's Message Translator feature to convert data to lowerCase.
Once data is converted to lowerCase using Message Translator, we need to define the destination where converted data will be stored.
This is the updated Camel Route in camel-context.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
  http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

 <camelContext xmlns="http://camel.apache.org/schema/spring">
  
  <route>
   
   <!-- Read files from input directory -->
   <from uri="file://data/input" />   
   <!-- Transform content to UpperCase using custom processor -->
   <process ref="myFileProcessor" />   
   <!-- Write converted file content -->
   <to uri="file://data/outputUppperCase" />
   
   <!-- Transform content to LowerCase using message translator -->
   <transform>
    <simple>${body.toLowerCase()}</simple>
   </transform>   
   <!-- Write converted file content -->
   <to uri="file://data/outputLowerCase" />   
  </route>
 
 </camelContext>

 <bean id="myFileProcessor" class="org.apache.camel.processor.FileProcessor" />
</beans>

7. Create Application Runner.

Now let's create application runner to run this application. This class will load Camel context file. As this is Spring context we will load it exactly same way as we load Spring context file.
Create class org.apache.camel.main.App with main method to load camel-context.xml file as follow.

package org.apache.camel.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(final String[] args) throws Exception {
     //Load application context
     ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("camel-context.xml");
        Thread.sleep(5000);
        applicationContext.close();
    }
}

8. Create Input and Output Directories.


Create following directories mentioned in Camel Route in camel-context.xml file.
  • ApacheCamelFileProcessor/data/input
  • ApacheCamelFileProcessor/data/outputLowerCase
  • ApacheCamelFileProcessor/data/outputUppperCase
Create sample input file as ApacheCamelFileProcessor/data/input/sample.txt with data:
THIS IS UPPERCASE CONTENT. this is lowecase content.

9. Build and Run Application.


To build this application execute following maven command in ApacheCamelFileProcessor directory.
mvn clean install
Now let's run this application. To run this application you can either run our main class org.apache.camel.main.App from your IDE or you can execute following maven command:
mvn exec:java -Dexec.mainClass="org.apache.camel.main.App"
Once application run successfully, you can find following:
ApacheCamelFileProcessor/data/outputUppperCase/sample.txt with following content:
THIS IS UPPERCASE CONTENT. THIS IS LOWECASE CONTENT.
ApacheCamelFileProcessor/data/outputLowerCase/sample.txt with following content:
this is uppercase content. this is lowecase content.

Download complete project from Git repository.