camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > tutorial-osgi-camel-part2
Date Sat, 21 Nov 2009 09:01:07 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/tutorial-osgi-camel-part2">tutorial-osgi-camel-part2</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~christian%2Bschneider">Christian Schneider</a>
    </h4>
     Replacing the deprecated maven archetype syntax with new one. Adding eclipse:eclipse so only one command is needed
          <div id="versionComment" class="noteMacro" style="display:none; padding: 5px;">
     Replacing the deprecated maven archetype syntax with new one. Adding eclipse:eclipse so only one command is needed<br />
     </div>
          <br/>
     <div class="notificationGreySide">
         <h1><a name="tutorial-osgi-camel-part2-Introduction"></a>Introduction</h1>

<p>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.</p>

<p>Designing a <ins>S</ins>ervice <ins>O</ins>riented <ins>A</ins>rchitecture seems very obvious for most of us but implies that different parameters are taken into account :</p>
<ul class="alternate" type="square">
	<li>Identification of the layers of the application,</li>
	<li>Definition of the services,</li>
	<li>Granularity (what are the boundaries of a service, ...),</li>
	<li>Dependency with libraries,</li>
	<li>Testing and debugging strategies,</li>
	<li>Deployment procedure,</li>
	<li>Infrastructure</li>
</ul>


<p>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.</p>

<p>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 Apache Felix Karaf (now part of Apache ServiceMix 4).</p>

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

<p>Here is a short list of features supported by the Karaf:</p>

<ul>
	<li>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).</li>
	<li>Dynamic configuration: Services are usually configured through the ConfigurationAdmin OSGi service. Such configuration can be defined in Karaf using property files inside the <a href="/confluence/pages/createpage.action?spaceKey=CAMEL&amp;title=home&amp;linkCreation=true&amp;fromPageId=113428" class="createlink">home</a>/etc directory. These configurations are monitored and changes on the properties files will be propagated to the services.</li>
	<li>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)</li>
	<li>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.</li>
	<li>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.</li>
	<li>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.</li>
	<li>Remote access: use any SSH client to connect to Karaf and issue commands in the console</li>
	<li>Security framework based on JAAS</li>
	<li>Managing instances: Karaf provides simple commands for managing multiple instances. You can easily create, delete, start and stop instances of Karaf through the console.</li>
	<li>Supports the latest OSGi 4.2 containers: Apache Felix Framework 2.0.0 and Eclipse Equinox 3.5</li>
</ul>



<p>Here is a picture of the report incident application that this tutorial will cover :</p>

<p><img src="/confluence/download/attachments/113428/routing.jpg" align="absmiddle" border="0" /> </p>

<p>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 : <a href="http://camel.apache.org/bindy.html" rel="nofollow">camel-bindy</a> and for the Web Service <a href="http://camel.apache.org/cxf.html" rel="nofollow">camel-cxf component</a>. Each message transformed is placed in a queue handled by <a href="http://activemq.apache.org/" rel="nofollow">ActiveMQ</a> 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.<br/>
A small <a href="http://wicket.apache.org/" rel="nofollow">Apache Wicket</a> web application running in <a href="http://www.mortbay.org/jetty/" rel="nofollow">Jetty Web server</a> provide to the users a screen to consult the incidents created.</p>

<p>Remark : A bundle in the OSGI world represents component made by developer. For more info about OSGI, I recommend to have a look on <a href="http://www.osgi.org/About/WhatIsOSGi" rel="nofollow">OSGI</a> web site</p>

<p>The project has been cut into the following components :</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Maven project name = artifactId </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Is it a bundle ? </th>
</tr>
<tr>
<td class='confluenceTd'> reportincident.activemq </td>
<td class='confluenceTd'> configuration file of the ActiveMQ engine </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.camelqueueservice </td>
<td class='confluenceTd'> configuration file of the camel-activemq component </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.db </td>
<td class='confluenceTd'> generator of the script DB </td>
<td class='confluenceTd'> no </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.features </td>
<td class='confluenceTd'> features provisioning file containing our bundles dependencies </td>
<td class='confluenceTd'> no </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.model </td>
<td class='confluenceTd'> model layer </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.persistence </td>
<td class='confluenceTd'> hibernate persistence layer; bundle </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.routing </td>
<td class='confluenceTd'> camel routing </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.service </td>
<td class='confluenceTd'> spring service layer </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.web </td>
<td class='confluenceTd'> apache wicket module </td>
<td class='confluenceTd'> yes </td>
</tr>
<tr>
<td class='confluenceTd'> reportincident.webservice </td>
<td class='confluenceTd'> CXF web service generator </td>
<td class='confluenceTd'> yes </td>
</tr>
</tbody></table>

<p>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. </p>

<h2><a name="tutorial-osgi-camel-part2-Prerequisites"></a>Prerequisites</h2>

<p>This tutorial uses:</p>
<ul class="alternate" type="square">
	<li><a href="http://maven.apache.org/download.html" rel="nofollow">Maven 2.0.9</a> to setup the projects,</li>
	<li><a href="http://www.eclipse.org/downloads/packages/" rel="nofollow">Eclipse Ganymede 3.4.x</a>,</li>
	<li><a href="http://m2eclipse.sonatype.org/" rel="nofollow">Maven eclipse plugin</a>,</li>
	<li><a href="http://felix.apache.org/site/downloads.cgi" rel="nofollow">Apache Felix Karaf 1.0</a>,</li>
	<li>Dependencies (= jars) used by the tutorial will be downloaded (if not available locally) by Maven</li>
</ul>


<p><b>Note:</b> The sample project can be downloaded, see the <a href="#tutorial-osgi-camel-part2-Resources">resources</a> section.</p>

<h2><a name="tutorial-osgi-camel-part2-Step1%3AInitialProjectSetup"></a>Step 1 : Initial Project Setup</h2>

<p>Different way exist to create maven project. For the basic project like db, we have used the archetype 'simple' with the command followed by <tt>mvn eclipse:eclipse</tt> in the folder created :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"> 
mvn archetype:generate -DinteractiveMode=<span class="code-keyword">false</span> -DgroupId=org.apache.camel.example -DartifactId=reportincident.model -Dversion=1.0-SNAPSHOT -Dgoals=eclipse:eclipse
</pre>
</div></div>

<p>For the OSGI bundles, different approaches are available depending on the tools that you prefer to use :</p>
<ul class="alternate" type="square">
	<li><a href="http://www.springsource.org/node/361" rel="nofollow">Spring archetype</a></li>
	<li><a href="http://www.springsource.org/bundlor" rel="nofollow">Spring bundlor</a></li>
	<li><a href="http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/" rel="nofollow">PAX maven plugin</a></li>
</ul>


<p>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 :</p>
<ul class="alternate" type="square">
	<li>pom.xml file generated is very simple to use and to understand,</li>
	<li>project can be designed with several modules,</li>
	<li>project can be tested with <a href="http://wiki.ops4j.org/display/paxexam/Pax+Exam" rel="nofollow">PAX Exam</a> and launched using <a href="http://wiki.ops4j.org/display/paxrunner/Pax+Runner" rel="nofollow">PAX runner</a></li>
	<li>generate all the folders required including also the META-INF,</li>
	<li>manifest file is generated automatically,</li>
	<li>can be imported easily in Eclipse</li>
</ul>


<p>To create the tutorial projects, you can follow the procedure described here </p>

<p>1) Execute maven command in your Unix/Dos console :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
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
</pre>
</div></div>
<p>2) Move to the folder created and execute the following command :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn org.ops4j:maven-pax-plugin:eclipse
</pre>
</div></div>
<p>2) Import the generated eclipse project in Eclipse workspace<br/>
3) Delete non required files like readme.txt and the folders internal + java class created<br/>
4) Enable dependency management (see <a href="http://docs.codehaus.org/display/M2ECLIPSE/Home" rel="nofollow">sonatype</a> site).</p>

<p>Repeat this procedure for the projects : </p>

<ul class="alternate" type="square">
	<li>reportincident.activemq</li>
	<li>reportincident.camelqueueservice</li>
	<li>reportincident.persistence</li>
	<li>reportincident.routing</li>
	<li>reportincident.service</li>
	<li>reportincident.web</li>
	<li>reportincident.webservice</li>
</ul>


<p>otherwise import the content of the unzipped file in your workspace. You will gain time.</p>

<h2><a name="tutorial-osgi-camel-part2-Step2%3ADevelopmodellayer"></a>Step 2 : Develop model layer</h2>

<p>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.<br/>
The reportincident model is really simple because it only contains one class that we will use :</p>
<ul class="alternate" type="square">
	<li>to map information with the database, CSV file,</li>
	<li>to transport information to web screens.</li>
</ul>


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

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> java.io.Serializable;

<span class="code-keyword">public</span> class Incident <span class="code-keyword">implements</span> Serializable{

	<span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-object">long</span> serialVersionUID = 1L;
	
	<span class="code-keyword">private</span> <span class="code-object">long</span> incidentId;

	<span class="code-keyword">private</span> <span class="code-object">String</span> incidentRef;
	
	<span class="code-keyword">private</span> Date incidentDate;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> givenName;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> familyName;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> summary;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> details;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> email;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> phone;
	
	<span class="code-keyword">private</span> <span class="code-object">String</span> creationUser;
	
	<span class="code-keyword">private</span> Date creationDate;
	
	
	<span class="code-keyword">public</span> <span class="code-object">long</span> getIncidentId() {
		<span class="code-keyword">return</span> incidentId;
	}

	<span class="code-keyword">public</span> void setIncidentId(<span class="code-object">long</span> incidentId) {
		<span class="code-keyword">this</span>.incidentId = incidentId;
	}
	
	<span class="code-keyword">public</span> <span class="code-object">String</span> getIncidentRef() {
		<span class="code-keyword">return</span> incidentRef;
	}

	<span class="code-keyword">public</span> void setIncidentRef(<span class="code-object">String</span> incidentRef) {
		<span class="code-keyword">this</span>.incidentRef = incidentRef;
	}

	<span class="code-keyword">public</span> Date getIncidentDate() {
		<span class="code-keyword">return</span> incidentDate;
	}

	<span class="code-keyword">public</span> void setIncidentDate(Date incidentDate) {
		<span class="code-keyword">this</span>.incidentDate = incidentDate;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getGivenName() {
		<span class="code-keyword">return</span> givenName;
	}

	<span class="code-keyword">public</span> void setGivenName(<span class="code-object">String</span> givenName) {
		<span class="code-keyword">this</span>.givenName = givenName;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getFamilyName() {
		<span class="code-keyword">return</span> familyName;
	}

	<span class="code-keyword">public</span> void setFamilyName(<span class="code-object">String</span> familyName) {
		<span class="code-keyword">this</span>.familyName = familyName;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getSummary() {
		<span class="code-keyword">return</span> summary;
	}

	<span class="code-keyword">public</span> void setSummary(<span class="code-object">String</span> summary) {
		<span class="code-keyword">this</span>.summary = summary;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getDetails() {
		<span class="code-keyword">return</span> details;
	}

	<span class="code-keyword">public</span> void setDetails(<span class="code-object">String</span> details) {
		<span class="code-keyword">this</span>.details = details;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getEmail() {
		<span class="code-keyword">return</span> email;
	}

	<span class="code-keyword">public</span> void setEmail(<span class="code-object">String</span> email) {
		<span class="code-keyword">this</span>.email = email;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getPhone() {
		<span class="code-keyword">return</span> phone;
	}

	<span class="code-keyword">public</span> void setPhone(<span class="code-object">String</span> phone) {
		<span class="code-keyword">this</span>.phone = phone;
	}

	<span class="code-keyword">public</span> <span class="code-object">String</span> getCreationUser() {
		<span class="code-keyword">return</span> creationUser;
	}

	<span class="code-keyword">public</span> void setCreationUser(<span class="code-object">String</span> creationUser) {
		<span class="code-keyword">this</span>.creationUser = creationUser;
	}

	<span class="code-keyword">public</span> Date getCreationDate() {
		<span class="code-keyword">return</span> creationDate;
	}

	<span class="code-keyword">public</span> void setCreationDate(Date creationDate) {
		<span class="code-keyword">this</span>.creationDate = creationDate;
	}

}
</pre>
</div></div>

<h2><a name="tutorial-osgi-camel-part2-Step3%3AMapmodellayerwithCSVfile%28camelbindy%29"></a>Step 3 : Map model layer with CSV file (camel-bindy)</h2>

<p>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 : <a href="http://camel.apache.org/bindy.html" rel="nofollow">camel-bindy</a>. Like its name suggests, camel-bindy is a binding framework (similar to JAXB2) 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, ....  </p>

<p>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 :</p>

<p>1) Add CSVRecord annotation</p>

<p>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</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.camel.dataformat.bindy.annotation.CsvRecord;

@CsvRecord(separator =<span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Incident <span class="code-keyword">implements</span> Serializable{
...
}
</pre>
</div></div>

<p>2) Add DataFields annotations</p>

<p>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.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">import</span> org.apache.camel.dataformat.bindy.annotation.CsvRecord;
<span class="code-keyword">import</span> org.apache.camel.dataformat.bindy.annotation.DataField;

@CsvRecord(separator =<span class="code-quote">","</span>)
<span class="code-keyword">public</span> class Incident <span class="code-keyword">implements</span> Serializable{

    @DataField(pos = 1)
    <span class="code-keyword">private</span> <span class="code-object">String</span> incidentRef;
	
    @DataField(pos = 2, pattern = <span class="code-quote">"dd-mm-yyyy"</span>)
    <span class="code-keyword">private</span> Date incidentDate;
	
    @DataField(pos = 3)
    <span class="code-keyword">private</span> <span class="code-object">String</span> givenName;
	
    @DataField(pos = 4)
    <span class="code-keyword">private</span> <span class="code-object">String</span> familyName;
	
    @DataField(pos = 5)
    <span class="code-keyword">private</span> <span class="code-object">String</span> summary;

    @DataField(pos = 6)
    <span class="code-keyword">private</span> <span class="code-object">String</span> details;
	
    @DataField(pos = 7)
    <span class="code-keyword">private</span> <span class="code-object">String</span> email;
	
    @DataField(pos = 8)
    <span class="code-keyword">private</span> <span class="code-object">String</span> phone;

...
}
</pre>
</div></div>

<p>To build the project, simply execute the following maven command in the reportincident.model project</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn clean install
</pre>
</div></div>

<h2><a name="tutorial-osgi-camel-part2-Step4%3AMapmodellayerwithDB%28Hibernate%29"></a>Step 4 : Map model layer with DB (Hibernate)</h2>

<p>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.</p>

<p>Remark : The ORM uses to persist the information is Hibernate but it can be changed to another existing like iBatis, Apache OpenJPA, ...</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;hibernate-mapping schema=<span class="code-quote">"REPORT"</span>&gt;</span>
	<span class="code-tag">&lt;class name=<span class="code-quote">"org.apache.camel.example.reportincident.model.Incident"</span> table=<span class="code-quote">"T_INCIDENT"</span>&gt;</span>
		<span class="code-tag">&lt;meta attribute=<span class="code-quote">"extends"</span>&gt;</span>Abstract<span class="code-tag">&lt;/meta&gt;</span>
		<span class="code-tag">&lt;id name=<span class="code-quote">"incidentId"</span> column=<span class="code-quote">"INCIDENT_ID"</span>  type=<span class="code-quote">"long"</span>&gt;</span>
			<span class="code-tag">&lt;generator class=<span class="code-quote">"native"</span> /&gt;</span>
		<span class="code-tag">&lt;/id&gt;</span>
		
		<span class="code-tag">&lt;property column=<span class="code-quote">"INCIDENT_REF"</span> name=<span class="code-quote">"incidentRef"</span> length=<span class="code-quote">"55"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"INCIDENT_DATE"</span> lazy=<span class="code-quote">"false"</span> length=<span class="code-quote">"8"</span> name=<span class="code-quote">"incidentDate"</span> type=<span class="code-quote">"timestamp"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"GIVEN_NAME"</span> length=<span class="code-quote">"35"</span> name=<span class="code-quote">"givenName"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"FAMILY_NAME"</span> length=<span class="code-quote">"35"</span> name=<span class="code-quote">"familyName"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"SUMMARY"</span> length=<span class="code-quote">"35"</span> name=<span class="code-quote">"summary"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"DETAILS"</span> length=<span class="code-quote">"255"</span> name=<span class="code-quote">"details"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"EMAIL"</span> length=<span class="code-quote">"60"</span> name=<span class="code-quote">"email"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"PHONE"</span> length=<span class="code-quote">"35"</span> name=<span class="code-quote">"phone"</span> type=<span class="code-quote">"string"</span> /&gt;</span>

		<span class="code-tag">&lt;property column=<span class="code-quote">"CREATION_DATE"</span> generated=<span class="code-quote">"never"</span> lazy=<span class="code-quote">"false"</span> name=<span class="code-quote">"creationDate"</span> type=<span class="code-quote">"timestamp"</span> /&gt;</span>
		<span class="code-tag">&lt;property column=<span class="code-quote">"CREATION_USER"</span> generated=<span class="code-quote">"never"</span> lazy=<span class="code-quote">"false"</span> name=<span class="code-quote">"creationUser"</span> type=<span class="code-quote">"string"</span> /&gt;</span>
	<span class="code-tag">&lt;/class&gt;</span>
<span class="code-tag">&lt;/hibernate-mapping&gt;</span>
</pre>
</div></div>

<p>Remark : This file <tt>Incident.hbm.xml</tt> must be created in the directory <tt>src\main\resources\META-INF\org\apache\camel\example\reportincident\model\Incident.hbm.xml</tt> of the project reportincident.model.</p>

<h2><a name="tutorial-osgi-camel-part2-Step6%3ADatabasecreation"></a>Step 6 : Database creation</h2>

<p>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.</p>

<p>Remark : MySQL has been used for the purpose of the tutorial</p>

<p>Here is the content of the hibernate.cfg.xml that you must create in the folder <tt>src/config</tt> of hibernate.db</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag"><span class="code-comment">&lt;!-- MySQL DB --&gt;</span></span>

<span class="code-tag">&lt;hibernate-configuration&gt;</span>
	<span class="code-tag">&lt;session-factory name=<span class="code-quote">"reportincident"</span>&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.connection.driver_class"</span>&gt;</span>com.mysql.jdbc.Driver<span class="code-tag">&lt;/property&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.connection.url"</span>&gt;</span>jdbc:mysql:///report<span class="code-tag">&lt;/property&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.connection.username"</span>&gt;</span>root<span class="code-tag">&lt;/property&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.dialect"</span>&gt;</span>org.hibernate.dialect.MySQL5Dialect<span class="code-tag">&lt;/property&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.connection.password"</span> /&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"hibernate.show_sql"</span>&gt;</span>true<span class="code-tag">&lt;/property&gt;</span>
		
	<span class="code-tag"><span class="code-comment">&lt;!-- mapping files --&gt;</span></span>
        <span class="code-tag">&lt;mapping resource=<span class="code-quote">"META-INF/org/apache/camel/example/reportincident/model/Incident.hbm.xml"</span>/&gt;</span>
		
	<span class="code-tag">&lt;/session-factory&gt;</span>
<span class="code-tag">&lt;/hibernate-configuration&gt;</span>
</pre>
</div></div> 

<p>The pom.xml file of your reportincident.db project must be modified like this :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>
&lt;project xmlns=<span class="code-quote">"http://maven.apache.org/POM/4.0.0"</span> <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
	xsi:schemaLocation=<span class="code-quote">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span>&gt;
	<span class="code-tag">&lt;modelVersion&gt;</span>4.0.0<span class="code-tag">&lt;/modelVersion&gt;</span>
	<span class="code-tag">&lt;groupId&gt;</span>org.apache.camel.example<span class="code-tag">&lt;/groupId&gt;</span>
	<span class="code-tag">&lt;artifactId&gt;</span>reportincident.db<span class="code-tag">&lt;/artifactId&gt;</span>
	<span class="code-tag">&lt;packaging&gt;</span>jar<span class="code-tag">&lt;/packaging&gt;</span>
	<span class="code-tag">&lt;name&gt;</span>Report Incident DB <span class="code-tag">&lt;/name&gt;</span>
	<span class="code-tag">&lt;version&gt;</span>1.0-SNAPSHOT<span class="code-tag">&lt;/version&gt;</span>

	<span class="code-tag">&lt;dependencies&gt;</span>
		<span class="code-tag">&lt;dependency&gt;</span> (1)
			<span class="code-tag">&lt;groupId&gt;</span>org.apache.camel.example<span class="code-tag">&lt;/groupId&gt;</span>
			<span class="code-tag">&lt;artifactId&gt;</span>reportincident.model<span class="code-tag">&lt;/artifactId&gt;</span>
			<span class="code-tag">&lt;version&gt;</span>1.0-SNAPSHOT<span class="code-tag">&lt;/version&gt;</span>
		<span class="code-tag">&lt;/dependency&gt;</span>
	<span class="code-tag">&lt;/dependencies&gt;</span>

	<span class="code-tag">&lt;build&gt;</span>
		<span class="code-tag">&lt;plugins&gt;</span>

			<span class="code-tag"><span class="code-comment">&lt;!-- Hibernate  plugin --&gt;</span></span>
			<span class="code-tag">&lt;plugin&gt;</span>
				<span class="code-tag">&lt;groupId&gt;</span>org.codehaus.mojo<span class="code-tag">&lt;/groupId&gt;</span>
				<span class="code-tag">&lt;artifactId&gt;</span>hibernate3-maven-plugin<span class="code-tag">&lt;/artifactId&gt;</span>
				<span class="code-tag">&lt;version&gt;</span>2.2<span class="code-tag">&lt;/version&gt;</span>
				<span class="code-tag">&lt;configuration&gt;</span>
					<span class="code-tag">&lt;components&gt;</span>
						<span class="code-tag">&lt;component&gt;</span>
							<span class="code-tag">&lt;name&gt;</span>hbm2ddl<span class="code-tag">&lt;/name&gt;</span>
						<span class="code-tag">&lt;/component&gt;</span>
					<span class="code-tag">&lt;/components&gt;</span>
					<span class="code-tag">&lt;componentProperties&gt;</span>
						<span class="code-tag">&lt;drop&gt;</span>true<span class="code-tag">&lt;/drop&gt;</span>
						<span class="code-tag">&lt;create&gt;</span>true<span class="code-tag">&lt;/create&gt;</span>
						<span class="code-tag">&lt;format&gt;</span>true<span class="code-tag">&lt;/format&gt;</span>
						<span class="code-tag">&lt;configurationfile&gt;</span>/src/config/hibernate.cfg.xml<span class="code-tag">&lt;/configurationfile&gt;</span>
						<span class="code-tag">&lt;outputfilename&gt;</span>db_reportincident_create_hsqldb.sql<span class="code-tag">&lt;/outputfilename&gt;</span>
					<span class="code-tag">&lt;/componentProperties&gt;</span>
				<span class="code-tag">&lt;/configuration&gt;</span>
				<span class="code-tag">&lt;dependencies&gt;</span>
					<span class="code-tag">&lt;dependency&gt;</span> (2)
						<span class="code-tag">&lt;groupId&gt;</span>mysql<span class="code-tag">&lt;/groupId&gt;</span>
						<span class="code-tag">&lt;artifactId&gt;</span>mysql-connector-java<span class="code-tag">&lt;/artifactId&gt;</span>
						<span class="code-tag">&lt;version&gt;</span>5.1.6<span class="code-tag">&lt;/version&gt;</span>
					<span class="code-tag">&lt;/dependency&gt;</span>
				<span class="code-tag">&lt;/dependencies&gt;</span>

				<span class="code-tag">&lt;executions&gt;</span>
					<span class="code-tag">&lt;execution&gt;</span>
						<span class="code-tag">&lt;phase&gt;</span>process-classes<span class="code-tag">&lt;/phase&gt;</span>
						<span class="code-tag">&lt;goals&gt;</span>
							<span class="code-tag">&lt;goal&gt;</span>hbm2ddl<span class="code-tag">&lt;/goal&gt;</span>
						<span class="code-tag">&lt;/goals&gt;</span>
					<span class="code-tag">&lt;/execution&gt;</span>
				<span class="code-tag">&lt;/executions&gt;</span>

			<span class="code-tag">&lt;/plugin&gt;</span>

		<span class="code-tag">&lt;/plugins&gt;</span>
	<span class="code-tag">&lt;/build&gt;</span>
<span class="code-tag">&lt;/project&gt;</span>
</pre>
</div></div>

<p>Remarks :<br/>
(1) - Dependency with reportincident.model project must be added because the plugin requires the file <tt>Incident.hbm.xml</tt> to generate the script/db<br/>
(2) - 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 </p>

<p>To create the table + SQL script, simply launch </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn clean install
</pre>
</div></div>
<p>command in the folder of reportincident.db </p>

<h2><a name="tutorial-osgi-camel-part2-Step7%3AAddpersistencelayerandSpringservice"></a>Step 7 : Add persistence layer and Spring service</h2>

<p>Now that the model/db exist, we will create the persistence and layer services. The projects have been designed using the pattern <ins>D</ins>ata <ins>A</ins>ccess <ins>O</ins>bject 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.   </p>

<h3><a name="tutorial-osgi-camel-part2-Persistenceproject"></a>Persistence project</h3>

<p>First, we will create the interface declaring the methods that we would like to provide/expose. Create in the folder <tt>src/main/java/org/apache/camel/example/reportincident/dao</tt>, the java class "IncidentDAO" with the following code :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.reportincident.dao;

<span class="code-keyword">import</span> java.util.List;

<span class="code-keyword">import</span> org.apache.camel.example.reportincident.model.Incident;

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> IncidentDAO
{

    /**
     * Gets the Incident.
     * 
     * @param id the id
     * @<span class="code-keyword">return</span> the incident
     */
    <span class="code-keyword">public</span> Incident getIncident( <span class="code-object">long</span> id );

    /**
     * Find all incidents.
     * 
     * @<span class="code-keyword">return</span> the list&lt;Incident&gt;
     */
    <span class="code-keyword">public</span> List&lt;Incident&gt; findIncident();

    /**
     * Find Incident using incident id ref.
     * 
     * @param key the key
     * @<span class="code-keyword">return</span> the list&lt; order&gt;
     */
    <span class="code-keyword">public</span> List&lt;Incident&gt; findIncident( <span class="code-object">String</span> key );

    /**
     * Save Incident.
     * 
     * @param incident the Incident
     */
    <span class="code-keyword">public</span> void saveIncident( Incident incident );

    /**
     * Removes the Incident.
     * 
     * @param id the id
     */
    <span class="code-keyword">public</span> void removeIncident( <span class="code-object">long</span> id );

}
</pre>
</div></div>

<p>There is nothing particular to mention here as this class is a simple case of <ins>C</ins>reate <ins>R</ins>ead <ins>U</ins>pdate <ins>D</ins>elete implementation. The next class who implements the interface will provide the necessary code to connect to the database using Hibernate framework.</p>

<p>So, create the class <tt>IncidentDAOImpl</tt> in the directory <tt>src/main/java/org/apache/camel/example/reportincident/dao/impl</tt></p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.reportincident.dao.impl;


<span class="code-keyword">import</span> java.util.List;

<span class="code-keyword">import</span> org.apache.camel.example.reportincident.dao.IncidentDAO;
<span class="code-keyword">import</span> org.apache.camel.example.reportincident.model.Incident;
<span class="code-keyword">import</span> org.apache.commons.logging.Log;
<span class="code-keyword">import</span> org.apache.commons.logging.LogFactory;
<span class="code-keyword">import</span> org.hibernate.HibernateException;
<span class="code-keyword">import</span> org.hibernate.Query;
<span class="code-keyword">import</span> org.hibernate.SessionFactory;
<span class="code-keyword">import</span> org.hibernate.impl.SessionImpl;


<span class="code-keyword">public</span> class IncidentDAOImpl <span class="code-keyword">implements</span> IncidentDAO
{

	<span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-keyword">transient</span> Log LOG = LogFactory.getLog(IncidentDAOImpl.class);
	
    /** The session factory. */
    <span class="code-keyword">private</span> SessionFactory sessionFactory;

    /** The q. */
    <span class="code-keyword">private</span> Query q = <span class="code-keyword">null</span>;

    /** The Constant findIncidentByReference. */
    <span class="code-keyword">private</span> <span class="code-keyword">final</span> <span class="code-keyword">static</span> <span class="code-object">String</span> findIncidentByReference =
        <span class="code-quote">"select i from Incident as i where i.incidentRef = :ref"</span>;

    /** The Constant findIncident. */
    <span class="code-keyword">private</span> <span class="code-keyword">final</span> <span class="code-keyword">static</span> <span class="code-object">String</span> findIncident =
        <span class="code-quote">"select i from Incident as i"</span>;
    
    /**
     * Sets the session factory.
     * 
     * @param sessionFactory the <span class="code-keyword">new</span> session factory
     */
    <span class="code-keyword">public</span> void setSessionFactory( SessionFactory sessionFactory )
    {
        <span class="code-keyword">this</span>.sessionFactory = sessionFactory;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.camel.example.reportincident.dao.IncidentDAO#findIncident()
     */
    <span class="code-keyword">public</span> List&lt;Incident&gt; findIncident()
        <span class="code-keyword">throws</span> HibernateException
    {

        <span class="code-comment">// Prepare query
</span>        q = <span class="code-keyword">this</span>.sessionFactory.getCurrentSession().createQuery( findIncident );

        <span class="code-comment">// Retrieve the Incidents from database
</span>        List&lt;Incident&gt; list = q.list();

        <span class="code-keyword">return</span> list;

    }

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

        <span class="code-keyword">return</span> list;
    }

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

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

    }

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

}
</pre>
</div></div>

<p>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.</p>

<p>The injection is defined in the file called <tt>spring-dao-beans.xml</tt> that you will create in the folder <tt>src/main/resources/META-INF/spring</tt> :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span> 
       <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
	   xsi:schemaLocation="
	     http://www.springframework.org/schema/beans
	     http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
	
	<span class="code-tag"><span class="code-comment">&lt;!-- DAO Declarations --&gt;</span></span>
	<span class="code-tag">&lt;bean id=<span class="code-quote">"incidentDAO"</span> class=<span class="code-quote">"org.apache.camel.example.reportincident.dao.impl.IncidentDAOImpl"</span>&gt;</span>
		<span class="code-tag">&lt;property name=<span class="code-quote">"sessionFactory"</span>&gt;</span>
			<span class="code-tag">&lt;ref bean=<span class="code-quote">"sessionFactory"</span> /&gt;</span>
		<span class="code-tag">&lt;/property&gt;</span>
	<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>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. </p>

<p>So realize this goal, you will create the file <tt>spring-datasource-beans.xml</tt> in the same folder directory with the following information :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
...
	<span class="code-tag"><span class="code-comment">&lt;!--  Hibernate SessionFactory Definition --&gt;</span></span>
	<span class="code-tag">&lt;bean id=<span class="code-quote">"sessionFactory"</span> class=<span class="code-quote">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span>&gt;</span>

		<span class="code-tag">&lt;property name=<span class="code-quote">"mappingLocations"</span>&gt;</span>
			<span class="code-tag">&lt;list&gt;</span>
				<span class="code-tag">&lt;value&gt;</span>classpath*:META-INF/org/apache/camel/example/reportincident/model/*.hbm.xml<span class="code-tag">&lt;/value&gt;</span>
			<span class="code-tag">&lt;/list&gt;</span>
		<span class="code-tag">&lt;/property&gt;</span>

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

</pre>
</div></div>

<p>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</p>

<h3><a name="tutorial-osgi-camel-part2-SpringServiceproject"></a>Spring Service project</h3>

<p>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, ...</p>

<p>Create the following interface <tt>IncidentService</tt> in the folder <tt>src/main/java/org/apache/camel/example/reportincident/service</tt> with the code :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.reportincident.service;

<span class="code-keyword">import</span> java.util.List;

<span class="code-keyword">import</span> org.apache.camel.example.reportincident.model.Incident;

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> IncidentService
{

    /**
     * Gets incident.
     * 
     * @param id the id
     * @<span class="code-keyword">return</span> the incident
     */
    <span class="code-keyword">public</span> Incident getIncident( <span class="code-object">long</span> id );

    /**
     * Find all Incidents.
     * 
     * @<span class="code-keyword">return</span> the list&lt;Incident&gt;
     */
    <span class="code-keyword">public</span> List&lt;Incident&gt; findIncident();

    /**
     * Find Incident by key ref.
     * 
     * @param key the key
     * @<span class="code-keyword">return</span> the list&lt; order&gt;
     */
    <span class="code-keyword">public</span> List&lt;Incident&gt; findIncident( <span class="code-object">String</span> key );

    /**
     * Save Incident.
     * 
     * @param incident the Incident
     */
    <span class="code-keyword">public</span> void saveIncident( Incident incident );

    /**
     * Removes the Incident.
     * 
     * @param id the id
     */
    <span class="code-keyword">public</span> void removeIncident( <span class="code-object">long</span> id );

}
</pre>
</div></div>

<p>and its implementation <tt>IncidentServiceImpl</tt> in the folder <tt>src/main/java/org/apache/camel/example/reportincident/service</tt> </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.reportincident.service.impl;

<span class="code-keyword">import</span> java.util.List;

<span class="code-keyword">import</span> org.apache.camel.example.reportincident.model.Incident;
<span class="code-keyword">import</span> org.apache.camel.example.reportincident.dao.IncidentDAO;
<span class="code-keyword">import</span> org.apache.camel.example.reportincident.service.IncidentService;
<span class="code-keyword">import</span> org.apache.commons.logging.Log;
<span class="code-keyword">import</span> org.apache.commons.logging.LogFactory;

<span class="code-keyword">public</span> class IncidentServiceImpl <span class="code-keyword">implements</span> IncidentService {
	
	<span class="code-keyword">private</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-keyword">transient</span> Log LOG = LogFactory.getLog(IncidentServiceImpl.class);

	/** The incident dao. */
	<span class="code-keyword">private</span> IncidentDAO incidentDAO;

	<span class="code-keyword">public</span> void saveIncident(Incident incident) {

		<span class="code-keyword">try</span> {
			getIncidentDAO().saveIncident(incident);
		} <span class="code-keyword">catch</span> (RuntimeException e) {
			e.printStackTrace();
		}

	}

	<span class="code-keyword">public</span> void removeIncident(<span class="code-object">long</span> id) {
		getIncidentDAO().removeIncident(id);
	}

	<span class="code-keyword">public</span> Incident getIncident(<span class="code-object">long</span> id) {
		<span class="code-keyword">return</span> getIncidentDAO().getIncident(id);
	}

	<span class="code-keyword">public</span> List&lt;Incident&gt; findIncident() {
		<span class="code-keyword">return</span> getIncidentDAO().findIncident();
	}

	<span class="code-keyword">public</span> List&lt;Incident&gt; findIncident(<span class="code-object">String</span> key) {
		<span class="code-keyword">return</span> getIncidentDAO().findIncident(key);
	}

	/**
	 * Gets the incident dao.
	 * 
	 * @<span class="code-keyword">return</span> the incident dao
	 */
	<span class="code-keyword">public</span> IncidentDAO getIncidentDAO() {
		<span class="code-keyword">return</span> incidentDAO;
	}

	/**
	 * Sets the incident dao.
	 * 
	 * @param incidentDAO
	 *            the <span class="code-keyword">new</span> incident dao
	 */
	<span class="code-keyword">public</span> void setIncidentDAO(IncidentDAO incidentDAO) {
		<span class="code-keyword">this</span>.incidentDAO = incidentDAO;
	}

}
</pre>
</div></div>

<p>The same remark as explained previously applies here concerning the DAO injection. So, you will create the following file <tt>spring-service-beans-dao.xml</tt> in the folder <tt>src/main/resources/META-INF/spring</tt> to inject the dependency of the DAO to our service.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
	<span class="code-tag">&lt;bean id=<span class="code-quote">"incidentServiceTarget"</span> class=<span class="code-quote">"org.apache.camel.example.reportincident.service.impl.IncidentServiceImpl"</span>&gt;</span>
            <span class="code-tag">&lt;property name=<span class="code-quote">"incidentDAO"</span>&gt;</span>
			...
	    <span class="code-tag">&lt;/property&gt;</span>
	<span class="code-tag">&lt;/bean&gt;</span>
</pre>
</div></div>

<p>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.</p>

<h2><a name="tutorial-osgi-camel-part2-Step8%3AWebservice"></a>Step 8 : Webservice</h2>

<p>This part has already been discussed in detail in the excellent tutorial : <a href="http://cwiki.apache.org/CAMEL/tutorial-example-reportincident.html" rel="nofollow">Report Incident - This tutorial introduces Camel steadily and is based on a real life integration problem</a>. So we will only explain what we have done specifically for our project.</p>

<p>Compare to the other tutorial, we have packaged the code generated by the CXF framework in a project/bundle separated from the routing/mediation engine. This approach allows you to extend your web services (I mean the methods exposed) without impacting the rest of your application. The question concerning the model is mush more delicate because we have a dependency on the model created to persist information. In our case, we have separated the webservice model (where the fields available are all declared as string) from ours but you can considered to have the same when Types are compatible (e.g. Can I map the Date Time object of my webservice field to my model without any transformation ?).</p>

<p>To generate the code that our application will use, we will work with following WSDL contract <tt>report_incident.wsdl</tt> that you create in the directory <tt>src/main/resources/META-INF/wsdl</tt>:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span> encoding=<span class="code-quote">"UTF-8"</span>?&gt;</span>

&lt;wsdl:definitions <span class="code-keyword">xmlns:soap</span>=<span class="code-quote">"http://schemas.xmlsoap.org/wsdl/soap/"</span>
	<span class="code-keyword">xmlns:tns</span>=<span class="code-quote">"http://reportincident.example.camel.apache.org"</span>
	<span class="code-keyword">xmlns:xs</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema"</span>
	<span class="code-keyword">xmlns:http</span>=<span class="code-quote">"http://schemas.xmlsoap.org/wsdl/http/"</span>
	<span class="code-keyword">xmlns:wsdl</span>=<span class="code-quote">"http://schemas.xmlsoap.org/wsdl/"</span>
	targetNamespace=<span class="code-quote">"http://reportincident.example.camel.apache.org"</span>&gt;

    <span class="code-tag"><span class="code-comment">&lt;!-- Type definitions for input- and output parameters for webservice --&gt;</span></span>
    <span class="code-tag">&lt;wsdl:types&gt;</span>
        <span class="code-tag">&lt;xs:schema targetNamespace=<span class="code-quote">"http://reportincident.example.camel.apache.org"</span>&gt;</span>
            <span class="code-tag">&lt;xs:element name=<span class="code-quote">"inputReportIncident"</span>&gt;</span>
                <span class="code-tag">&lt;xs:complexType name=<span class="code-quote">"inputReportIncident"</span>&gt;</span>
                    <span class="code-tag">&lt;xs:sequence&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"incidentId"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"incidentDate"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"givenName"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"familyName"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"summary"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"details"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"email"</span>/&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"phone"</span>/&gt;</span>
                    <span class="code-tag">&lt;/xs:sequence&gt;</span>
                <span class="code-tag">&lt;/xs:complexType&gt;</span>
            <span class="code-tag">&lt;/xs:element&gt;</span>
            <span class="code-tag">&lt;xs:element name=<span class="code-quote">"outputReportIncident"</span>&gt;</span>
                <span class="code-tag">&lt;xs:complexType name=<span class="code-quote">"outputReportIncident"</span>&gt;</span>
                    <span class="code-tag">&lt;xs:sequence&gt;</span>
                        <span class="code-tag">&lt;xs:element type=<span class="code-quote">"xs:string"</span> name=<span class="code-quote">"code"</span>/&gt;</span>
                    <span class="code-tag">&lt;/xs:sequence&gt;</span>
                <span class="code-tag">&lt;/xs:complexType&gt;</span>
            <span class="code-tag">&lt;/xs:element&gt;</span>
        <span class="code-tag">&lt;/xs:schema&gt;</span>
    <span class="code-tag">&lt;/wsdl:types&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- Message definitions for input and output --&gt;</span></span>
    <span class="code-tag">&lt;wsdl:message name=<span class="code-quote">"inputReportIncident"</span>&gt;</span>
        <span class="code-tag">&lt;wsdl:part name=<span class="code-quote">"in"</span> element=<span class="code-quote">"tns:inputReportIncident"</span>/&gt;</span>
    <span class="code-tag">&lt;/wsdl:message&gt;</span>
    <span class="code-tag">&lt;wsdl:message name=<span class="code-quote">"outputReportIncident"</span>&gt;</span>
        <span class="code-tag">&lt;wsdl:part name=<span class="code-quote">"out"</span> element=<span class="code-quote">"tns:outputReportIncident"</span>/&gt;</span>
    <span class="code-tag">&lt;/wsdl:message&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- Port (interface) definitions --&gt;</span></span>
    <span class="code-tag">&lt;wsdl:portType name=<span class="code-quote">"ReportIncidentEndpoint"</span>&gt;</span>
        <span class="code-tag">&lt;wsdl:operation name=<span class="code-quote">"ReportIncident"</span>&gt;</span>
            <span class="code-tag">&lt;wsdl:input message=<span class="code-quote">"tns:inputReportIncident"</span>/&gt;</span>
            <span class="code-tag">&lt;wsdl:output message=<span class="code-quote">"tns:outputReportIncident"</span>/&gt;</span>
        <span class="code-tag">&lt;/wsdl:operation&gt;</span>
    <span class="code-tag">&lt;/wsdl:portType&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- Port bindings to transports and encoding - HTTP, document literal encoding is used --&gt;</span></span>
    <span class="code-tag">&lt;wsdl:binding name=<span class="code-quote">"ReportIncidentBinding"</span> type=<span class="code-quote">"tns:ReportIncidentEndpoint"</span>&gt;</span>
        <span class="code-tag">&lt;soap:binding transport=<span class="code-quote">"http://schemas.xmlsoap.org/soap/http"</span>/&gt;</span>
        <span class="code-tag">&lt;wsdl:operation name=<span class="code-quote">"ReportIncident"</span>&gt;</span>
            &lt;soap:operation
                    soapAction=<span class="code-quote">"http://reportincident.example.camel.apache.org/ReportIncident"</span>
                    style=<span class="code-quote">"document"</span>/&gt;
            <span class="code-tag">&lt;wsdl:input&gt;</span>
                <span class="code-tag">&lt;soap:body parts=<span class="code-quote">"in"</span> use=<span class="code-quote">"literal"</span>/&gt;</span>
            <span class="code-tag">&lt;/wsdl:input&gt;</span>
            <span class="code-tag">&lt;wsdl:output&gt;</span>
                <span class="code-tag">&lt;soap:body parts=<span class="code-quote">"out"</span> use=<span class="code-quote">"literal"</span>/&gt;</span>
            <span class="code-tag">&lt;/wsdl:output&gt;</span>
        <span class="code-tag">&lt;/wsdl:operation&gt;</span>
    <span class="code-tag">&lt;/wsdl:binding&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- Service definition --&gt;</span></span>
    <span class="code-tag">&lt;wsdl:service name=<span class="code-quote">"ReportIncidentEndpointService"</span>&gt;</span>
        <span class="code-tag">&lt;wsdl:port name=<span class="code-quote">"ReportIncidentPort"</span> binding=<span class="code-quote">"tns:ReportIncidentBinding"</span>&gt;</span>
            <span class="code-tag">&lt;soap:address location=<span class="code-quote">"http://localhost:8080/camel-example/incident"</span>/&gt;</span>
        <span class="code-tag">&lt;/wsdl:port&gt;</span>
    <span class="code-tag">&lt;/wsdl:service&gt;</span>

<span class="code-tag">&lt;/wsdl:definitions&gt;</span>
</pre>
</div></div>
<p>The code will be generated thanks to a maven plugin : cxf-codegen-plugin.</p>

<p>Add the following line in your <tt>pom.xml</tt> of the project <tt>reportincident.webservice</tt></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag"><span class="code-comment">&lt;!-- CXF wsdl2java generator, will plugin to the compile goal --&gt;</span></span>
			<span class="code-tag">&lt;plugin&gt;</span>
				<span class="code-tag">&lt;groupId&gt;</span>org.apache.cxf<span class="code-tag">&lt;/groupId&gt;</span>
				<span class="code-tag">&lt;artifactId&gt;</span>cxf-codegen-plugin<span class="code-tag">&lt;/artifactId&gt;</span>
				<span class="code-tag">&lt;version&gt;</span>${cxf-version}<span class="code-tag">&lt;/version&gt;</span>
				<span class="code-tag">&lt;executions&gt;</span>
					<span class="code-tag">&lt;execution&gt;</span>
						<span class="code-tag">&lt;id&gt;</span>generate-sources<span class="code-tag">&lt;/id&gt;</span>
						<span class="code-tag">&lt;phase&gt;</span>generate-sources<span class="code-tag">&lt;/phase&gt;</span>
						<span class="code-tag">&lt;configuration&gt;</span>
							<span class="code-tag">&lt;sourceRoot&gt;</span>${basedir}/target/generated/src/main/java<span class="code-tag">&lt;/sourceRoot&gt;</span>
							<span class="code-tag">&lt;wsdlOptions&gt;</span>
								<span class="code-tag">&lt;wsdlOption&gt;</span>
									<span class="code-tag">&lt;wsdl&gt;</span>${basedir}/src/main/resources/META-INF/wsdl/report_incident.wsdl<span class="code-tag">&lt;/wsdl&gt;</span>
								<span class="code-tag">&lt;/wsdlOption&gt;</span>
							<span class="code-tag">&lt;/wsdlOptions&gt;</span>
						<span class="code-tag">&lt;/configuration&gt;</span>
						<span class="code-tag">&lt;goals&gt;</span>
							<span class="code-tag">&lt;goal&gt;</span>wsdl2java<span class="code-tag">&lt;/goal&gt;</span>
						<span class="code-tag">&lt;/goals&gt;</span>
					<span class="code-tag">&lt;/execution&gt;</span>
				<span class="code-tag">&lt;/executions&gt;</span>

			<span class="code-tag">&lt;/plugin&gt;</span>
</pre>
</div></div>
<p>The code is generated using the maven command :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn generate-sources
</pre>
</div></div>
<p>Remark : the code is generated in the directory <tt>target/src/main/java</tt></p>

<h2><a name="tutorial-osgi-camel-part2-Conclusion"></a>Conclusion</h2>

<p>Everything is in place to integrate the services together except the routing and OSGI stuffs. This is what we will cover in the following sections.</p>

<p>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.</p>

<h2><a name="tutorial-osgi-camel-part2-Links"></a>Links</h2>

<ul class="alternate" type="square">
	<li>Part 2 : real example, architecture, project setup, database creation</li>
	<li><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2a" title="tutorial-osgi-camel-part2a">Part 2a : transform projects in bundles</a></li>
	<li><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2b" title="tutorial-osgi-camel-part2b">Part 2b : add infrastructure and routing</a></li>
	<li><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2c" title="tutorial-osgi-camel-part2c">Part 2c : web and deployment</a></li>
</ul>


<h2><a name="tutorial-osgi-camel-part2-%23Resources"></a><a href="#tutorial-osgi-camel-part2-Resources">Resources</a></h2>

<ul>
	<li>
    
    

            <table class="tableview attachments">
            <tr>
                                    <th>&nbsp;</th>
                                <th><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2?sortBy=name">Name</a></th>
                <th><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2?sortBy=size">Size</a></th>
                <th>Creator (Last Modifier)</th>
                <th><a href="/confluence/display/CAMEL/tutorial-osgi-camel-part2?sortBy=date">Creation Date</a></th>
                <th>Last Mod Date</th>
                <th>Comment</th>
                                    <th>&nbsp;</th>
                            </tr>

            
                <tr class="currentAttachmentRow">
                                    <td><img align="absmiddle" height="16" width="16" src="/confluence/images/border/spacer.gif"></td>
                                    <td><a name="tutorial-osgi-camel-part2-attachment-tutorial-osgi-camel-part2.zip"><img src="/confluence/images/icons/attachments/zip.gif" height=16 width=16 border=0 vspace=1 align=absmiddle alt="ZIP Archive"></a> <a href="/confluence/download/attachments/113428/tutorial-osgi-camel-part2.zip">tutorial-osgi-camel-part2.zip</a></td>
                    <td>569 kB</td>
                    <td><a href="/confluence/display/~cmoulliard@xpectis.com">Charles Moulliard</a> </td>
                    <td>Nov 20, 2009</td>
                    <td>Nov 20, 2009</td>
                    <td>                            &nbsp;
                                            </td>
                                        <td>
                                                                                                          <a  id="editAttachmentLink"  href="/confluence/pages/editattachment.action?pageId=113428&fileName=tutorial-osgi-camel-part2.zip" >Edit</a>
                                                                                  |                             <a  id="removeAttachmentLink"  href="/confluence/pages/removeattachment.action?pageId=113428&fileName=tutorial-osgi-camel-part2.zip&version=1"  class="deleteAttachmentLink" >Remove</a>
                                                            <fieldset class="hidden">
                                    <input type="hidden" name="i18n-deleteConfirmMessage" value="Are you sure you want to remove attached file tutorial-osgi-camel-part2.zip?" />
                                </fieldset>
                                                                         </td>
                                    </tr>
                                    
                    </table>
    
    </li>
</ul>

     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/tutorial-osgi-camel-part2">View Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=113428&revisedVersion=49&originalVersion=48">View Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/tutorial-osgi-camel-part2?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message