INTRODUCTION
- JBOSS Fuse is a open source Enterprise Service Bus (ESB).
- It is a lightweight and modular integration platform.
The aim of this tutorial is to
- Create an application using Apache Camel
- Deploy the application into JBOSS Fuse ESB.
USECASE
- Enroll students for the Engineering Admission by various Colleges.
- Get the request as XML and copy it to a folder
SOFTWARES & TOOLS
- Eclipse IDE
- Java 1.8
- Maven
INSTALLATIONS
- Download JBoss Fuse ESB (jboss-fuse-6.2.0.redhat-133) from JBoss Official Website
- Extract the zip into your local : ~/softwares/jboss-fuse-6.2.0
- Install RESTClient in Chrome/Firefox browser.
IMPLEMENTATION
Step 1
Create a Maven project and copy the below into pom.xml
<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.jbr.jbossfuse</groupId>
<artifactId>FuseFirst</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>FuseFirst</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.0.RELEASE</spring.version>
<slf4j.version>1.7.10</slf4j.version>
<cxf.version>3.0.0</cxf.version>
<camel.version>2.13.0</camel.version>
<felix.maven.bundle.plugin.version>2.5.3</felix.maven.bundle.plugin.version>
</properties>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<!-- Adding this plugin as an extension enables packaging=bundle (i.e.
osgi bundle). This plugin will automatically add most of the OSGi meta-information
to the generated OSGi bundle (jar file with extra entries in META-INF/MANIFEST.MF) -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${felix.maven.bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>*</Import-Package>
<Private-Package>
</Private-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- SPRING -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<version>${camel.version}</version>
<scope>test</scope>
</dependency>
<!-- CAMEL -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<!-- CFX -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-aegis</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-local</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- LOGGER -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
|
Step 2
Create XML Schema for the usecase.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="EnrollmentDetails">
<xs:complexType>
<xs:sequence>
<xs:element name="CollegeName" type="xs:string"></xs:element>
<xs:element name="CollegeCode" type="xs:string"></xs:element>
<xs:element name="Student">
<xs:complexType>
<xs:sequence>
<xs:element name="EnrollmentId" type="xs:int"></xs:element>
<xs:element name="StudentName" type="xs:string"></xs:element>
<xs:element name="Address" type="xs:string"></xs:element>
<xs:element name="DateOfBirth" type="xs:string"></xs:element>
<xs:element name="Age" type="xs:int"></xs:element>
<xs:element name="Gender" type="xs:string"></xs:element>
<xs:element name="ContactNumber" type="xs:int"></xs:element>
<xs:element name="Email" type="xs:string"></xs:element>
<xs:element name="EducationInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="Qualification" type="xs:string"></xs:element>
<xs:element name="Grade" type="xs:string"></xs:element>
<xs:element name="YearOfPassing" type="xs:int"></xs:element>
<xs:element name="EntranceScore" type="xs:int"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
|
Step 3
Create sample XML data.
<?xml version="1.0" encoding="UTF-8"?>
<EnrollmentDetails>
<CollegeName>MIT</CollegeName>
<CollegeCode>TN201</CollegeCode>
<Student>
<EnrollmentId>200</EnrollmentId>
<StudentName>Ranjith</StudentName>
<Address>Chennai</Address>
<DateOfBirth>15-May-1990</DateOfBirth>
<Age>25</Age>
<Gender>Male</Gender>
<ContactNumber>9600037466</ContactNumber>
<Email>ranjith@gmail.com</Email>
<EducationInfo>
<Qualification>HSS</Qualification>
<Grade>First</Grade>
<YearOfPassing>2015</YearOfPassing>
<EntranceScore>250</EntranceScore>
</EducationInfo>
</Student>
</EnrollmentDetails>
|
Step 4
Perform Marshalling and Unmarshalling using JAXB. Create Java Classes from the XSD.
- Create a new package (com.jbr.jbossfuse.beans)
- Right click the XSD file -> Generate - > JAXB Classes
- Select the newly Project: FuseExample -> Click Next
- Select the package: com.jbr.jbossfuse.beans -> Click Finish
- Now, the classes would be created in the package.
Step 5
Create Entry Point.
1. Create an Interface for Enrollment.
package com.jbr.jbossfuse;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import com.jbr.jbossfuse.beans.EnrollmentDetails;
@WebService
@Path("/")
@Consumes("application/xml")
@Produces("application/xml")
public interface Enrollment {
@WebMethod
@POST
@Path("/enrollStudent")
EnrollmentDetails enrollStudent(String enrollmentDetails);
}
|
2. Write an implementation for Enrollment.
package com.jbr.jbossfuse;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import com.jbr.jbossfuse.beans.EnrollmentDetails;
@WebService
@Path("/")
@Consumes("application/xml")
@Produces("application/xml")
public class NationalCollegeEnrollment implements Enrollment {
@WebMethod
@POST
@Path("/enrollStudent")
public EnrollmentDetails enrollStudent(String enrollmentDetails) {
throw new IllegalStateException("Invalid Request or Other Error. Check configuration");
}
}
|
Step 6
Creating a route.
package com.jbr.jbossfuse;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EnrollmentRouter extends RouteBuilder {
final public static Logger logger = LoggerFactory.getLogger(EnrollmentRouter.class);
// Create a REST Service Request URL.
private String restServiceUrl = "cxfrs://http://127.0.0.1:1834/enrollmentService?resourceClasses=com.jbr.jbossfuse.NationalCollegeEnrollment";
// OUTPUT file location in the JBOSS FUSE ESB
private String requestFilePath = "file://enrollment/request";
/**
* This method is default method of RouteBuilder class. It will be called only
* ONCE when starting the FEATURE.
*/
@Override
public void configure() throws Exception {
logger.info("Enter - EnrollmentRouter.confgure");
/**
* from(restServiceUrl) - Get the request from the REST Request.
* routeId("EnrollmentRouterId") - is an id for the Route.
* to("direct:EnrollStudent") - is and EndPoint, called by other process.
*/
from(restServiceUrl).log("Saturday-Received message Inbound route of EnrollmentRouter")
.routeId("EnrollmentRouterId").to("direct:EnrollStudent").end();
/**
* from("direct:EnrollStudent") - get the data from end point.
* to(requestFilePath) - send the response to the folder.
*/
from("direct:EnrollStudent").to(requestFilePath).end();
logger.info("Exit - EnrollmentRouter.confgure");
}
}
|
Step 7
Add resources as below
1. Create a folder "META-INF" under ~\FuseFirst\src\main\resources
2. Create a folder "spring" under ~\FuseFirst\src\main\resources\META-INF
3. Create a context 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:osgix="http://www.springframework.org/schema/osgi-compendium"
xmlns:ctx="http://www.springframework.org/schema/context"
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-2.15.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/osgi-compendium
http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd">
<camelContext trace="false" id="camelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="enrollmentRouter" />
</camelContext>
<bean id="enrollmentRouter" class="com.jbr.jbossfuse.EnrollmentRouter" />
</beans>
|
Step 8
Build the Maven application using below steps.
1. Right click the pom.xml file and Select "Maven clean"
2. Right click the pom.xml file and Select "Maven install"
Step 9
Create features by below configuration (filename: FuseFeatures.xml).
<?xml version="1.0" encoding="UTF-8"?>
<features name="MyFeaturesRepo">
<feature name="StudentEnrollment">
<bundle>file:C:/ranjiths/GD/j2r/ws/ws-jbossfuse/FuseExample/target/FuseExample-0.0.1-SNAPSHOT.jar
</bundle>
</feature>
</features>
|
Now our code implementation is over and time to Deploy into Fuse ESB.
DEPLOYMENT
Follow the below steps to deploy the application.
- Start the fuse by clicking ~jboss-fuse-6.2.0.redhat-133\bin\fuse.bat
JBossFuse:karaf@root>
- Install the feature
JBossFuse:karaf@root> features:addurl file:c:/ranjiths/GD/j2r/ws/ws-jbossfuse/FuseExample/FuseFeatures.xml
JBossFuse:karaf@root> features:install StudentEnrollment -> Enter
Note: StudentEnrollment - feature name in FuseFeatures.xml file
- Issue below command to check whether StudentEnrollment feature is started or not.
JBossFuse:karaf@root> list
You will get the output as below
[ 267] [Active ] [ ] [Started] [ 80] FuseExample (0.0.1.SNAPSHOT)
TESTING THE FEATURE
Follow the below steps to test our new StudentEnrollment feature.
- Open the RESTClient
- Copy the URL (http://127.0.0.1:1834/enrollmentService) from EnrollmentRouter.java
- Append /enrollStudent copied from EnrollmentDetails.java
- Final URL: http://127.0.0.1:1834/enrollmentService/enrollStudent
- Copy the content of EnrollStudent.xml into the Payload
- Select 'POST' Method
- Select Content-Type as application/xml
- Click 'Send'
- The xmls content will be copied with file name ID-XXX under ~jboss-fuse-6.2.0.redhat-133\enrollment\request
Please reply if you are getting any errors during execution. Also share your thoughts in the comment box.
Happy Knowledge Sharing!!!