Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Designing a Service Oriented Architecture seems very obvious for most of us but implies that different parameters are taken into account :

  • Identification of the layers of the application,
  • Definition of the services,
  • Granularity (what are the boundaries of a service, ...),
  • Dependency with libraries,
  • Testing and debugging strategies,
  • Deployment procedure,
  • Infrastructure

Some of the points mentioned are particular to SOA world like granularity and definition of service boundaries but others are mostly found in all IT projects. This is really important to keep them in your head because they will impact the project life cycle, quality of the deliverable, efficiency of the team and project duration/cost.

In this second part of the tutorial we will investigate some of the points mentioned and applied them to a real application. The application will be designed around different components (= bundles in the OSGI jargon) and deployed into ServiceMix Kernel. ServiceMix Kernel or SMXKNL is an OSGI platform created top of Apache Felix OSGI server, integrating Spring Dynamic Modules to facilitate the build of Spring application and PAX components who provide tools managing deployment of component and web support. For more information about the projects/frameworks mentioned, I recommend that you have a look on their respective web site. Apache Felix Karaf (now part of Apache ServiceMix 4).

Apache Karaf is a small OSGi based runtime which provides a lightweight container onto which various components and applications can be deployed.

Here is a short list of features supported by the Karaf:

  • Hot deployment: Karaf supports hot deployment of OSGi bundles by monitoring jar files inside the home/deploy directory. Each time a jar is copied in this folder, it will be installed inside the runtime. You can then update or delete it and changes will be handled automatically. In addition, the Karaf also supports exploded bundles and custom deployers (blueprint and spring ones are included by default).
  • Dynamic configuration: Services are usually configured through the ConfigurationAdmin OSGi service. Such configuration can be defined in Karaf using property files inside the home/etc directory. These configurations are monitored and changes on the properties files will be propagated to the services.
  • Logging System: using a centralized logging back end supported by Log4J, Karaf supports a number of different APIs (JDK 1.4, JCL, SLF4J, Avalon, Tomcat, OSGi)
  • Provisioning: Provisioning of libraries or applications can be done through a number of different ways, by which they will be downloaded locally, installed and started.
  • Native OS integration: Karaf can be integrated into your own Operating System as a service so that the lifecycle will be bound to your Operating System.
  • Extensible Shell console: Karaf features a nice text console where you can manage the services, install new applications or libraries and manage their state. This shell is easily extensible by deploying new commands dynamically along with new features or applications.
  • Remote access: use any SSH client to connect to Karaf and issue commands in the console
  • Security framework based on JAAS
  • Managing instances: Karaf provides simple commands for managing multiple instances. You can easily create, delete, start and stop instances of Karaf through the console.
  • Supports the latest OSGi 4.2 containers: Apache Felix Framework 2.0.0 and Eclipse Equinox 3.5

Here is a picture of the report incident application that this tutorial will cover :

...

Prerequisites

This tutorial uses:

...

...

  • 4.0,
  • Dependencies (= jars) used by the tutorial will be downloaded (if not available locally) by Maven

Note: The sample project can be downloaded, see the resources section.

...

Different way exist to create maven project. For the basic project like db, we have used the archetype 'simple' with the command followed by mvn eclipse:eclipse in the folder created :

Code Block
 
mvn archetype:creategenerate -DartifactIdDinteractiveMode=simplefalse -DgroupId=org.apache.camel.example -DartifactId=reportincident.model -Dversion=1.0-SNAPSHOT
cd reportincident.db
mvn  -Dgoals=eclipse:eclipse

For the OSGI bundles, different approaches are available depending on the tools that you prefer to use :

But for the purpose of this tutorial, we have used the PAX maven plugin. Why this choice, simply because PAX maven plugin offers a lot of advantages regarding to the one of Spring :

  • pom.xml file generated is very simple to use and to understand,
  • project can be designed with several modules,
  • project can be tested with PAX Exam and launched using PAX runner
  • generate all the folders required including also the META-INF,
  • manifest file is generated automatically,
  • can be imported easily in Eclipse

To create the tutorial projects, you can follow the procedure described here

...

Repeat this procedure for the projects :

  • reportincident.activemq
  • reportincident.camelqueueservice
  • reportincident.persistence
  • reportincident.routing
  • reportincident.service
  • reportincident.web
  • reportincident.webservice

otherwise import the content of the unzipped file in your workspace. You will gain time.

...

It is time now to begin serious things. One of the most important part of a project (if not the most important) concerns the design of the model.
The reportincident model is really simple because it only contains one class that we will use :

  • to map information with the database, CSV file,
  • to transport information to web screens.

Here is the definition of the incident class that you can create in the reportincident.model project directory src/main/java/org/apache/camel/example/reportincident/model or use the code imported

Code Block
import java.io.Serializable;

public class Incident implements Serializable{

	private static final long serialVersionUID = 1L;
	
	protectedprivate long incidentId;

	protectedprivate String incidentRef;
	
	protectedprivate Date incidentDate;
	
	protectedprivate String givenName;
	
	protectedprivate String familyName;
	
	protectedprivate String summary;
	
	protectedprivate String details;
	
	protectedprivate String email;
	
	protectedprivate String phone;
	
	protectedprivate String creationUser;
	
	protectedprivate Date creationDate;
	
	
	public long getIncidentId() {
		return incidentId;
	}

	public void setIncidentId(long incidentId) {
		this.incidentId = incidentId;
	}
	
	public String getIncidentRef() {
		return incidentRef;
	}

	public void setIncidentRef(String incidentRef) {
		this.incidentRef = incidentRef;
	}

	public Date getIncidentDate() {
		return incidentDate;
	}

	public void setIncidentDate(Date incidentDate) {
		this.incidentDate = incidentDate;
	}

	public String getGivenName() {
		return givenName;
	}

	public void setGivenName(String givenName) {
		this.givenName = givenName;
	}

	public String getFamilyName() {
		return familyName;
	}

	public void setFamilyName(String familyName) {
		this.familyName = familyName;
	}

	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public String getDetails() {
		return details;
	}

	public void setDetails(String details) {
		this.details = details;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getCreationUser() {
		return creationUser;
	}

	public void setCreationUser(String creationUser) {
		this.creationUser = creationUser;
	}

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

}

...

To facilitate the work of the modeler, we will use the incident class not only to persist the information in the database but also to read or generate Comma Separate Value file (CSV). To map the content of the class with a CSV file, we have used a new Camel component : camel-bindy. Like its name suggests, camel-bindy is a binding framework (similar to JAXBJAXB2) to map non structured information with Java class using annotations. The current version supports CSV fields and key-value pairs (e.g. Financial FIX messages) but will be extended in the future to support Fixed Length format, ....

...

Code Block
import org.apache.camel.dataformat.bindy.annotation.CsvRecord;
import org.apache.camel.dataformat.bindy.annotation.DataField;

@CsvRecord(separator =",")
public class Incident implements Serializable{

    @DataField(pos = 01)
    protectedprivate String incidentRef;
	
    @DataField(pos = 12, pattern = "dd-mm-yyyy")
    protectedprivate Date incidentDate;
	
    @DataField(pos = 23)
    protectedprivate String givenName;
	
    @DataField(pos = 34)
    protectedprivate String familyName;
	
    @DataField(pos = 45)
    protectedprivate String summary;

    @DataField(pos = 56)
    protectedprivate String details;
	
    @DataField(pos = 67)
    protectedprivate String email;
	
    @DataField(pos = 78)
    protectedprivate String phone;

...
}

To build the project, simply execute the following maven command in the reportincident.model project

Code Block
mvn clean install

Step 4 : Map model layer with DB (Hibernate)

...

Code Block
xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<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.example</groupId>
	<artifactId>reportincident.db</artifactId>
	<packaging>jar</packaging>
	<name>Report Incident DB </name>
	<version>1.0-SNAPSHOT</version>

	<dependencies>
		<dependency> (1)
			<groupId>org.apache.camel.example</groupId>
			<artifactId>reportincident.model</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>

			<!-- Hibernate  plugin -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>hibernate3-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<components>
						<component>
							<name>hbm2ddl</name>
						</component>
					</components>
					<componentProperties>
						<drop>true</drop>
						<create>true</create>
						<format>true</format>
						<configurationfile>/src/config/hibernate.cfg.xml</configurationfile>
						<outputfilename>db_reportincident_create_hsqldb.sql</outputfilename>
					</componentProperties>
				</configuration>
				<dependencies>
					<dependency> (2)
						<groupId>mysql</groupId>
						<artifactId>mysql-connector-java</artifactId>
						<version>5.1.6<8</version>
					</dependency>
				</dependencies>

				<executions>
					<execution>
						<phase>process-classes</phase>
						<goals>
							<goal>hbm2ddl</goal>
						</goals>
					</execution>
				</executions>

			</plugin>

		</plugins>
	</build>
</project>

...

It is time now to have a break, to make some sport exercices, to drink a cup of good 'Java' coffee or to go outside of the building to take a walk with your favorite pets.

  • Part

...

  • 2 : real example, architecture, project setup, database creation
  • Part

...

...

...

#Resources

  • Attachments
    patterns.*part2.zip