Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

The purpose of this tutorial is not at all to teach you on SOA but to draw your attention on points that the

...

developer(s)/deployer(s)

...

will

...

be

...

confronted

...

during

...

the

...

design/development

...

and

...

release

...

management

...

phases.

...

Designing

...

a

...

S

...

ervice

...

O

...

riented

...

A

...

rchitecture

...

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.

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

Image Added

To summarize, the application is listening for incidents coming from web service or files. According to the origin, the content (= incidents) are transformed into their corresponding objects using for the CSV file, a new camel component : camel-bindy and for the Web Service camel-cxf component. Each message transformed is placed in a queue handled by ActiveMQ engine. All the messages (containing the objects) are next processed by a Bean service who will (with the help of injection of dependency provided by Spring) save the incidents in a DB using Spring and Hibernate frameworks.
A small Apache Wicket web application running in Jetty Web server provide to the users a screen to consult the incidents created.

Remark : A bundle in the OSGI world represents component made by developer. For more info about OSGI, I recommend to have a look on OSGI web site

The project has been cut into the following components :

Maven project name = artifactId

Description

Is it a bundle ?

reportincident.activemq

configuration file of the ActiveMQ engine

yes

reportincident.camelqueueservice

configuration file of the camel-activemq component

yes

reportincident.db

generator of the script DB

no

reportincident.features

features provisioning file containing our bundles dependencies

no

reportincident.model

model layer

yes

reportincident.persistence

hibernate persistence layer; bundle

yes

reportincident.routing

camel routing

yes

reportincident.service

spring service layer

yes

reportincident.web

apache wicket module

yes

reportincident.webservice

CXF web service generator

yes

As you can see, some are considered as OSGI bundles and others no. An important point to mention here concerns the granularity : each layer of our application will be deployed as separate bundle. This will facilitate the maintenance and release management. Of course, you can argue that the granularity is too small. SOA is not an exact science and depending of the size of the application, the team in charge to develop, release management procedure this cutting will be redefined. You can imagine that the parameters used to configure Hibernate and Spring are bundles together instead inside the persistence project. Service bundle could be split into several bundles; one by service type, ... There are no rules of thumb except that the project must be manageable and maintainable.

Prerequisites

This tutorial uses:

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

Step 1 : Initial Project Setup

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

- 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|http://felix.apache.org/site/index.html] OSGI server, integrating [Spring Dynamic Modules|http://www.springsource.org/osgi] to facilitate the build of Spring application and [PAX components|http://wiki.ops4j.org/display/ops4j/Pax] 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.   

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

!routing.jpg! 

To summarize, the application is listening for incidents coming from web service or files. According to the origin, the content (= incidents) are transformed into their corresponding objects using for the CSV file, a new camel component : [camel-bindy|http://camel.apache.org/bindy.html] and for the Web Service [camel-cxf component|http://camel.apache.org/cxf.html]. Each message transformed is placed in a queue handled by [ActiveMQ|http://activemq.apache.org/] engine. All the messages (containing the objects) are next processed by a Bean service who will (with the help of injection of dependency provided by Spring) save the incidents in a DB using Spring and Hibernate frameworks.
A small [Apache Wicket|http://wicket.apache.org/] web application running in [Jetty Web server|http://www.mortbay.org/jetty/] provide to the users a screen to consult the incidents created.

Remark : A bundle in the OSGI world represents component made by developer. For more info about OSGI, I recommend to have a look on [OSGI|http://www.osgi.org/About/WhatIsOSGi] web site

The project has been cut into the following components :

|| Maven project name = artifactId || Description || Is it a bundle ? ||
| reportincident.activemq | configuration file of the ActiveMQ engine | yes | 
| reportincident.camelqueueservice | configuration file of the camel-activemq component | yes |
| reportincident.db | generator of the script DB | no |
| reportincident.features | features provisioning file containing our bundles dependencies | no |
| reportincident.model | model layer | yes |
| reportincident.persistence | hibernate persistence layer; bundle | yes |
| reportincident.routing | camel routing | yes |
| reportincident.service | spring service layer | yes |
| reportincident.web | apache wicket module | yes |
| reportincident.webservice | CXF web service generator | yes |

As you can see, some are considered as OSGI bundles and others no. An important point to mention here concerns the granularity : each layer of our application will be deployed as separate bundle. This will facilitate the maintenance and release management. Of course, you can argue that the granularity is too small. SOA is not an exact science and depending of the size of the application, the team in charge to develop, release management procedure this cutting will be redefined. You can imagine that the parameters used to configure Hibernate and Spring are bundles together instead inside the persistence project. Service bundle could be split into several bundles; one by service type, ... There are no rules of thumb except that the project must be manageable and maintainable. 

h2. Prerequisites

This tutorial uses:
- [Maven 2.0.9|http://maven.apache.org/download.html] to setup the projects,
- [Eclipse Ganymede 3.4.x|http://www.eclipse.org/downloads/packages/],
- [Maven eclipse plugin|http://m2eclipse.sonatype.org/],
- [Service Mix Kernel 1.1.0|http://servicemix.apache.org/SMX4KNL/index.html],
- 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|#Resources] section.

h2. Step 1 : Initial Project Setup

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} 
mvn archetype:create -DartifactId=simple -DgroupId=org.apache.camel.example -DartifactId=reportincident.model -Dversion=1.0-SNAPSHOT
cd reportincident.db
mvn eclipse:eclipse
{code}

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

1) Execute maven command in your Unix/Dos console :

Code Block
 archetype|http://www.springsource.org/node/361]
- [Spring bundlor|http://www.springsource.org/bundlor]
- [PAX maven plugin|http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/]

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|http://wiki.ops4j.org/display/paxexam/Pax+Exam] and launched using [PAX runner|http://wiki.ops4j.org/display/paxrunner/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 

1) Execute maven command in your Unix/Dos console :
{code}
mvn org.ops4j:maven-pax-plugin:create-bundle -Dpackage=org.apache.camel.example.reportincident.model -DbundleGroupId=reportincident.model -DbundleName=reportincident.model -Dversion=1.0-SNAPSHOT
{code}

2)

...

Move

...

to

...

the

...

folder

...

created

...

and

...

execute

...

the

...

following

...

command

...

:

{
Code Block
}
mvn org.ops4j:maven-pax-plugin:eclipse
{code}

2)

...

Import

...

the

...

generated

...

eclipse

...

project

...

in

...

Eclipse

...

workspace

...


3)

...

Delete

...

non

...

required

...

files

...

like

...

readme.txt

...

and

...

the

...

folders

...

internal

...

+

...

java

...

class

...

created

...


4)

...

Enable

...

dependency

...

management

...

(see

...

sonatype

...

site).

...

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.

...

Step

...

2

...

:

...

Develop

...

model

...

layer

...

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;
	
	protected long incidentId;

	protected String incidentRef;
	
	protected Date incidentDate;
	
	protected String givenName;
	
	protected String familyName;
	
	protected String summary;
	
	protected String details;
	
	protected String email;
	
	protected String phone;
	
	protected String creationUser;
	
	protected 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;
	}

}
{code}

h2. Step 3 : Map model layer with CSV file 

Step 3 : Map model layer with CSV file (camel-bindy)

...

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.

...

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

...

JAXB)

...

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,

...

....

...

So,

...

we

...

will

...

modify

...

our

...

existing

...

class

...

to

...

add

...

@Annotations

...

required

...

to

...

map

...

its

...

content.

...

This

...

is

...

very

...

trivial

...

to

...

do

...

and

...

will

...

be

...

done

...

in

...

two

...

steps

...

:

...

1)

...

Add

...

CSVRecord

...

annotation

...

This

...

annotation

...

will

...

help

...

camel-bindy

...

to

...

discover

...

what

...

is

...

the

...

parent

...

class

...

of

...

the

...

model

...

and

...

which

...

separator

...

is

...

used

...

to

...

separate

...

the

...

fields.

...

If

...

required,

...

you

...

can

...

also

...

use

...

the

...

property

...

'skipFirstLine'

...

to

...

skip

...

the

...

first

...

line

...

of

...

your

...

CSV

...

file

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

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

2)

...

Add

...

DataFields

...

annotations

...

For

...

each

...

of

...

the

...

CSV

...

field

...

that

...

you

...

want

...

to

...

bind

...

with

...

your

...

model,

...

you

...

must

...

add

...

the

...

@DataField

...

annotation

...

with

...

its

...

position.

...

This

...

is

...

not

...

the

...

only

...

property

...

available

...

and

...

you

...

can

...

also

...

add

...

'pattern'

...

property

...

to

...

by

...

example

...

define

...

the

...

pattern

...

of

...

your

...

Date

...

field.

{
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 = 0)
    protected String incidentRef;
	
    @DataField(pos = 1, pattern = "dd-mm-yyyy")
    protected Date incidentDate;
	
    @DataField(pos = 2)
    protected String givenName;
	
    @DataField(pos = 3)
    protected String familyName;
	
    @DataField(pos = 4)
    protected String summary;

    @DataField(pos = 5)
    protected String details;
	
    @DataField(pos = 6)
    protected String email;
	
    @DataField(pos = 7)
    protected String phone;

...
}
{code}

h2. 

Step

...

4

...

:

...

Map

...

model

...

layer

...

with

...

DB

...

(Hibernate)

...

To

...

map

...

our

...

model

...

with

...

the

...

database,

...

we

...

will

...

use

...

the

...

ORM

...

framework

...

Hibernate.

...

Annotation

...

can

...

also

...

be

...

used

...

since

...

the

...

last

...

version

...

of

...

Hibernate

...

but

...

to

...

avoid

...

to

...

overload

...

our

...

class

...

and

...

reduce

...

its

...

readability,

...

we

...

will

...

use

...

the

...

old

...

way

...

using

...

a

...

XML

...

file

...

describing

...

the

...

mapping

...

between

...

the

...

model

...

and

...

the

...

database.

...

Remark

...

:

...

The

...

ORM

...

uses

...

to

...

persist

...

the

...

information

...

is

...

Hibernate

...

but

...

it

...

can

...

be

...

changed

...

to

...

another

...

existing

...

like

...

iBatis,

...

Apache

...

OpenJPA,

...

...

{
Code Block
}
<hibernate-mapping schema="REPORT">
	<class name="org.apache.camel.example.reportincident.model.Incident" table="T_INCIDENT">
		<meta attribute="extends">Abstract</meta>
		<id name="incidentId" column="INCIDENT_ID"  type="long">
			<generator class="native" />
		</id>
		
		<property column="INCIDENT_REF" name="incidentRef" length="55" type="string" />
		<property column="INCIDENT_DATE" lazy="false" length="8" name="incidentDate" type="timestamp" />
		<property column="GIVEN_NAME" length="35" name="givenName" type="string" />
		<property column="FAMILY_NAME" length="35" name="familyName" type="string" />
		<property column="SUMMARY" length="35" name="summary" type="string" />
		<property column="DETAILS" length="255" name="details" type="string" />
		<property column="EMAIL" length="60" name="email" type="string" />
		<property column="PHONE" length="35" name="phone" type="string" />

		<property column="CREATION_DATE" generated="never" lazy="false" name="creationDate" type="timestamp" />
		<property column="CREATION_USER" generated="never" lazy="false" name="creationUser" type="string" />
	</class>
</hibernate-mapping>
{code}

Remark

...

:

...

This

...

file

...

Incident.hbm.xml

...

must

...

be

...

created

...

in

...

the

...

directory

...

src\main\resources\META-INF\org\apache\camel\example\reportincident\model\Incident.hbm.xml

...

of

...

the

...

project

...

reportincident.model.

...

Step

...

6

...

:

...

Database

...

creation

...

To

...

create

...

the

...

database,

...

we

...

will

...

use

...

hibernate

...

maven

...

plugin

...

file.

...

The

...

plugin

...

will

...

use

...

the

...

following

...

configuration

...

file

...

to

...

generate

...

the

...

SQL

...

script

...

and

...

create

...

table

...

T_Incident.

...

Remark

...

:

...

MySQL

...

has

...

been

...

used

...

for

...

the

...

purpose

...

of

...

the

...

tutorial

...

Here

...

is

...

the

...

content

...

of

...

the

...

hibernate.cfg.xml

...

that

...

you

...

must

...

create

...

in

...

the

...

folder

...

src/config

...

of

...

hibernate.db

{
Code Block
}
<!-- MySQL DB -->

<hibernate-configuration>
	<session-factory name="reportincident">
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///report</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<property name="hibernate.connection.password" />
		<property name="hibernate.show_sql">true</property>
		
	<!-- mapping files -->
        <mapping resource="META-INF/org/apache/camel/example/reportincident/model/Incident.hbm.xml"/>
		
	</session-factory>
</hibernate-configuration>
{code} 

The 

The pom.xml

...

file

...

of

...

your

...

reportincident.db

...

project

...

must

...

be

...

modified

...

like

...

this

...

:

{
Code Block
}
<?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>
			<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>
						<groupId>mysql</groupId>
						<artifactId>mysql-connector-java</artifactId>
						<version>5.1.6</version>
					</dependency>
				</dependencies>

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

			</plugin>

		</plugins>
	</build>
</project>
{code}

Remarks

...

:

...

  • Dependency

...

  • with

...

  • reportincident.model

...

  • project

...

  • must

...

  • be

...

  • added

...

  • because

...

  • the

...

  • plugin

...

  • requires

...

  • the

...

  • file

...

  • Incident.hbm.xml

...

  • to

...

  • generate

...

  • the

...

  • script/db

...

  • If

...

  • you

...

  • prefer

...

  • to

...

  • use

...

  • another

...

  • DB

...

  • instead

...

  • of

...

  • MySql,

...

  • change

...

  • the

...

  • dependency

...

  • in

...

  • the

...

  • pom.xml

...

  • and

...

  • hibernate.connection.driver_class

...

  • and

...

  • hibernate.connection.url

...

  • in

...

  • the

...

  • cfg

...

  • file

...

To

...

create

...

the

...

table

...

+

...

SQL

...

script,

...

simply

...

launch

Code Block
 

{code}
mvn clean install
{code}

command

...

in

...

the

...

folder

...

of

...

reportincident.db

...

Step 7 : Add persistence layer and Spring service

Now that the model/db exist, we will create the persistence and layer services. The projects have been designed using the pattern Data Access Object because it allows to change the implementation from a database type to another, between ORM very easily. Moreover interfaces are used as 'contract' between the services and the DAO. This offers the advantage to decouple objects in the application and as you will see later on it will allow us to deploy services, persistence as separate bundles in the OSGI server.

1) Persistence project

First, we will create the interface declaring the methods that we would like to provide/expose. Create in the folder src/main/java/org/apache/camel/example/reportincident/dao

...

,

...

the

...

java

...

class

...

"IncidentDAO"

...

with

...

the

...

following

...

code

...

:

{
Code Block
}
package org.apache.camel.example.reportincident.dao;

import java.util.List;

import org.apache.camel.example.reportincident.model.Incident;

public interface IncidentDAO
{

    /**
     * Gets the Incident.
     * 
     * @param id the id
     * @return the incident
     */
    public Incident getIncident( long id );

    /**
     * Find all incidents.
     * 
     * @return the list<Incident>
     */
    public List<Incident> findIncident();

    /**
     * Find Incident using incident id ref.
     * 
     * @param key the key
     * @return the list< order>
     */
    public List<Incident> findIncident( String key );

    /**
     * Save Incident.
     * 
     * @param incident the Incident
     */
    public void saveIncident( Incident incident );

    /**
     * Removes the Incident.
     * 
     * @param id the id
     */
    public void removeIncident( long id );

}
{code}

There

...

is

...

nothing

...

particular

...

to

...

mention

...

here

...

as

...

this

...

class

...

is

...

a

...

simple

...

case

...

of

...

C

...

reate

...

R

...

ead

...

U

...

pdate

...

D

...

elete

...

implementation.

...

The

...

next

...

class

...

who

...

implements

...

the

...

interface

...

will

...

provide

...

the

...

necessary

...

code

...

to

...

connect

...

to

...

the

...

database

...

using

...

Hibernate

...

framework.

...

So,

...

create

...

the

...

class

...

IncidentDAOImpl

...

in

...

the

...

directory

...

src/main/java/org/apache/camel/example/reportincident/dao/impl

Code Block
}}

{code}
package org.apache.camel.example.reportincident.dao.impl;


import java.util.List;

import org.apache.camel.example.reportincident.dao.IncidentDAO;
import org.apache.camel.example.reportincident.model.Incident;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.impl.SessionImpl;


public class IncidentDAOImpl implements IncidentDAO
{

	private static final transient Log LOG = LogFactory.getLog(IncidentDAOImpl.class);
	
    /** The session factory. */
    private SessionFactory sessionFactory;

    /** The q. */
    private Query q = null;

    /** The Constant findIncidentByReference. */
    private final static String findIncidentByReference =
        "select i from Incident as i where i.incidentRef = :ref";

    /** The Constant findIncident. */
    private final static String findIncident =
        "select i from Incident as i";
    
    /**
     * Sets the session factory.
     * 
     * @param sessionFactory the new session factory
     */
    public void setSessionFactory( SessionFactory sessionFactory )
    {
        this.sessionFactory = sessionFactory;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#findIncident()
     */
    public List<Incident> findIncident()
        throws HibernateException
    {

        // Prepare query
        q = this.sessionFactory.getCurrentSession().createQuery( findIncident );

        // Retrieve the Incidents from database
        List<Incident> list = q.list();

        return list;

    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#findIncident(java.lang.String)
     */
    public List<Incident> findIncident( String key )
        throws HibernateException
    {
        q = this.sessionFactory.getCurrentSession().createQuery( findIncidentByReference );
        q.setString("ref", key );
        List<Incident> list = q.list();

        return list;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#getIncident(long)
     */
    public Incident getIncident( long id )
    {
        return (Incident) this.sessionFactory.getCurrentSession().get( Incident.class, id );
    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#removeIncident(long)
     */
    public void removeIncident( long id )
    {
        Object record = this.sessionFactory.getCurrentSession().load( Incident.class, id );
        this.sessionFactory.getCurrentSession().delete( record );

    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#saveIncident(org.apache.camel.example.reportincident.model.Incident)
     */
    public void saveIncident( Incident Incident )
    {
    	SessionImpl session = (SessionImpl) this.sessionFactory.getCurrentSession();
        this.sessionFactory.getCurrentSession().saveOrUpdate( Incident );
    }

}
{code}
 
The most important point to mention here is that this class to connect to our database and to work with Hibernate needs to have a SessionFactory object. This object is not instantiated by a constructor's class but only declared as a property/field. This is where Spring will help us through its dependency injection.

The injection is defined in the file called {{

The most important point to mention here is that this class to connect to our database and to work with Hibernate needs to have a SessionFactory object. This object is not instantiated by a constructor's class but only declared as a property/field. This is where Spring will help us through its dependency injection.

The injection is defined in the file called spring-dao-beans.xml

...

that

...

you

...

will

...

create

...

in

...

the

...

folder

...

src/main/resources/META-INF/spring :

Code Block
}} :

{code}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="
	     http://www.springframework.org/schema/beans
	     http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- DAO Declarations -->
	<bean id="incidentDAO" class="org.apache.camel.example.reportincident.dao.impl.IncidentDAOImpl">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>

</beans>
{code}

The

...

sessionFactory

...

object

...

will

...

be

...

created

...

with

...

the

...

help

...

of

...

Spring

...

framework

...

but

...

in

...

order

...

to

...

communicate

...

with

...

the

...

database,

...

information

...

about

...

the

...

data

...

source

...

must

...

be

...

provided.

...

So

...

realize

...

this

...

goal,

...

you

...

will

...

create

...

the

...

file

...

spring-datasource-beans.xml

...

in

...

the

...

same

...

folder

...

directory

...

with

...

the

...

following

...

information

...

:

{
Code Block
}
...
	<!--  Hibernate SessionFactory Definition -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

		<property name="mappingLocations">
			<list>
				<value>classpath*:META-INF/org/apache/camel/example/reportincident/model/*.hbm.xml</value>
			</list>
		</property>

		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">false</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
				<prop key="hibernate.jdbc.batch_size">10</prop>
				<prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
			</props>
		</property>
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
...
	<!--  DB connection and persistence layer -->
	<!--  DataSource Definition  -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${driverClassName}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
	</bean>

{code}

This

...

file

...

is

...

not

...

complete

...

but

...

we

...

will

...

review

...

later

...

in

...

the

...

tutorial

...

when

...

we

...

will

...

cover

...

specific

...

OSGI

...

stuffs

...

and

...

Spring

...

transaction

...

management.

...

Now,

...

we

...

will

...

design

...

the

...

Spring

...

service

...

part

...

2)

...

Spring

...

Service

...

project

...

In

...

term

...

of

...

design,

...

the

...

service

...

project

...

is

...

very

...

similar

...

to

...

the

...

persistence

...

because

...

we

...

will

...

create

...

an

...

interface

...

and

...

its

...

implementation.

...

Why

...

repeating

...

the

...

interface.

...

The

...

answer

...

is

...

evident;

...

it

...

is

...

for

...

decoupling

...

the

...

service

...

from

...

the

...

DAO

...

implentation

...

to

...

allow

...

you

...

to

...

switch

...

easily

...

from

...

one

...

ORM

...

to

...

another,

...

...

...

Create

...

the

...

following

...

interface

...

IncidentService

...

in

...

the

...

folder

...

src/main/java/org/apache/camel/example/reportincident/service

...

with

...

the

...

code

...

:

{
Code Block
}
package org.apache.camel.example.reportincident.service;

import java.util.List;

import org.apache.camel.example.reportincident.model.Incident;

public interface IncidentService
{

    /**
     * Gets incident.
     * 
     * @param id the id
     * @return the incident
     */
    public Incident getIncident( long id );

    /**
     * Find all Incidents.
     * 
     * @return the list<Incident>
     */
    public List<Incident> findIncident();

    /**
     * Find Incident by key ref.
     * 
     * @param key the key
     * @return the list< order>
     */
    public List<Incident> findIncident( String key );

    /**
     * Save Incident.
     * 
     * @param incident the Incident
     */
    public void saveIncident( Incident incident );

    /**
     * Removes the Incident.
     * 
     * @param id the id
     */
    public void removeIncident( long id );

}
{code}

and

...

its

...

implementation

...

IncidentServiceImpl

...

in

...

the

...

folder

...

src/main/java/org/apache/camel/example/reportincident/service

Code Block
}} 

{code}
package org.apache.camel.example.reportincident.service.impl;

import java.util.List;

import org.apache.camel.example.reportincident.model.Incident;
import org.apache.camel.example.reportincident.dao.IncidentDAO;
import org.apache.camel.example.reportincident.service.IncidentService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class IncidentServiceImpl implements IncidentService {
	
	private static final transient Log LOG = LogFactory.getLog(IncidentServiceImpl.class);

	/** The incident dao. */
	private IncidentDAO incidentDAO;

	public void saveIncident(Incident incident) {

		try {
			getIncidentDAO().saveIncident(incident);
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

	}

	public void removeIncident(long id) {
		getIncidentDAO().removeIncident(id);
	}

	public Incident getIncident(long id) {
		return getIncidentDAO().getIncident(id);
	}

	public List<Incident> findIncident() {
		return getIncidentDAO().findIncident();
	}

	public List<Incident> findIncident(String key) {
		return getIncidentDAO().findIncident(key);
	}

	/**
	 * Gets the incident dao.
	 * 
	 * @return the incident dao
	 */
	public IncidentDAO getIncidentDAO() {
		return incidentDAO;
	}

	/**
	 * Sets the incident dao.
	 * 
	 * @param incidentDAO
	 *            the new incident dao
	 */
	public void setIncidentDAO(IncidentDAO incidentDAO) {
		this.incidentDAO = incidentDAO;
	}

}
{code}

The

...

same

...

remark

...

as

...

explained

...

previously

...

applies

...

here

...

concerning

...

the

...

DAO

...

injection.

...

So,

...

you

...

will

...

create

...

the

...

following

...

file

...

spring-service-beans-dao.xml

...

in

...

the

...

folder

...

src/main/resources/META-INF/spring

...

to

...

inject

...

the

...

dependency

...

of

...

the

...

DAO

...

to

...

our

...

service.

{
Code Block
}
	<bean id="incidentServiceTarget" class="org.apache.camel.example.reportincident.service.impl.IncidentServiceImpl">
            <property name="incidentDAO">
			...
	    </property>
	</bean>
{code}

Obviously,

...

this

...

file

...

is

...

not

...

complete

...

because

...

the

...

reference

...

of

...

the

...

DAO

...

class

...

is

...

not

...

mentioned

...

except

...

the

...

property

...

name.

...

Don't

...

panic,

...

we

...

will

...

come

...

back

...

later

...

on

...

when

...

we

...

will

...

discuss

...

Spring

...

Blueprint

...

services.

...

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.

...

#Resources

  • Attachments
    patterns.*part2.zip

...