Transform existing projects into bundlesTo convert a project into a bundle a couple of things/steps must be done : 1) Declare the project in the maven pom.xml file as of type <packaging>bundle</packaging>,
Step 1 : reportincident.modelTo transform the reportincident.model project, we will execute the steps 1) 2) and 3) because no services must be registered for this project. So, update the pom.xml file created and add/change what is put in the code below in XML comment with word STEP <?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.model</artifactId> <!-- STEP 1 --> <packaging>bundle</packaging> <name>Report Incident Model Bundle</name> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.apache.camel.example</groupId> <artifactId>reportincident.parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> <dependencies> <!-- Camel bindy --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-bindy</artifactId> <version>${camel-version}</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>${commons-lang}</version> </dependency> </dependencies> <build> <plugins> <!-- to compile with 1.5 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <!-- STEP 2 --> <!-- to generate the MANIFEST-FILE of the bundle --> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <version>${felix-version}</version> <configuration> <manifestLocation>META-INF</manifestLocation> <instructions> <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> <!-- STEP 3 --> <Export-Package> '=META-INF.org.apache.camel.example.reportincident.model', org.apache.camel.example.reportincident.model </Export-Package> <_failok>true</_failok> </instructions> </configuration> </plugin> </plugins> </build> </project> Remarks :
When the pom.xml has been updated, you can execute the following maven command : mvn clean install org.ops4j:maven-pax-plugin:eclipse
This command will generate a jar file containing the classes, hibernate file and MANIFEST.MF file and deploy it in your maven local repository. You can open the jar and check if the the content of MANIFEST.MF is similar to Manifest-Version: 1.0 Export-Package: org.apache.camel.example.reportincident.model;uses:="o rg.apache.commons.lang.builder,org.apache.camel.dataformat.bindy.anno tation",META-INF.org.apache.camel.example.reportincident.model Built-By: Charlesm Build-Jdk: 1.6.0_12 Bundle-Version: 1.0.0.SNAPSHOT Tool: Bnd-0.0.255 Bundle-Name: Report Incident Model Bundle Bnd-LastModified: 1240844069542 Created-By: Apache Maven Bundle Plugin Bundle-ManifestVersion: 2 Bundle-SymbolicName: reportincident.model Import-Package: META-INF.org.apache.camel.example.reportincident.model ,org.apache.camel.dataformat.bindy.annotation;version="2.0.0.M1",org. apache.camel.example.reportincident.model,org.apache.commons.lang.bui lder;version="2.4" It is time to continue with the persistence project where we will introduce new important concepts Step 2 : reportincident.persistenceFirst, you have to replace the pom.xml file created with the file provided in the project attached (see resource). If you open this file, you will see that the <Import-Package> section of the maven-felix-plugin has been enriched with the packages required to work with Hibernate, Spring and JTA classes. Nevertheless, it is interesting to mention that we have exported the package org.apache.camel.example.reportincident.dao and defined org.apache.camel.example.reportincident.dao.impl as private. Why, the reason is very simple, we would like to export only the interface to another 'service' bundles and keep internally the implementation. <Private-Package>org.apache.camel.example.reportincident.dao.impl</Private-Package> <Export-Package>org.apache.camel.example.reportincident.dao</Export-Package>
In order to test the tip, update your pom.xml with the following info : <Import-Package> META-INF.org.apache.camel.example.reportincident.model, com.mysql.jdbc, org.apache.camel.example.reportincident.model, org.apache.commons.dbcp, * </Import-Package> <Private-Package> org.apache.camel.example.reportincident.dao.impl </Private-Package> <Export-Package> org.apache.camel.example.reportincident.dao </Export-Package> <DynamicImport-Package>*</DynamicImport-Package> and look at the result generated by the plugin. The Import-Package section is dry. Now that our pom.xml is configured we will modified our spring.xml files to allow our DAO service to be registered as a OSGI service. Why, because the classes of the bundle reportincident.service uses this DAO class but required also additional functionalities like (Hibernate SessionFactory, Spring Transaction management, ...) who will be instantiated and configured when the persistence bundle/service will be started. Additional motivations are also provided in the OSGI specification :
Create the file persistence-osgi.xml in the directory src/main/resources/META-INF/spring and add the lines : <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <osgi:service ref="incidentDAO" interface="org.apache.camel.example.reportincident.dao.IncidentDAO"/> </beans> The osgi:service namespace tells to Spring to register the interface org.apache.camel.example.reportincident.dao.IncidentDAO as a service in the OSGI registry. This feature proposed by Spring will be part of the next OSGI specification R4.2 under the name of Blueprint - RFC 124. Remark :
Another feature that I would like to introduce here concerns the Configuration Admin. In its simplest form, the CM can be seen as a configuration source, namely a Dictionary whose keys are always Strings. Spring DM can expose entries in the CM as a Properties object, through the cm-properties element. So, we can adapt our spring-datasource-beans.xml file created in the previous chapter with new xml tags :
<context:property-placeholder properties-ref="preProps" /> (1)
...
<osgix:cm-properties id="preProps" persistent-id="org.apache.camel.example.reportincident.datasource"> (2)
<prop key="driverClassName">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql:///report</prop>
<prop key="username"></prop>
<prop key="password"></prop>
</osgix:cm-properties>
...
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" /> (3)
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
The configuration above, exposes the properties available in the CM under org.apache.camel.example.reportincident.datasource entry (2) as a bean named preProps. Moreover, the property declared (3) can be override by creating a file named org.apache.camel.example.reportincident.datasource.cfg and containing the parameters :
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///report
username=root
password=
Spring using the context:property-placeholder (1) will be able to load it. Remarks :
Step 3 : reportincident.serviceLike for the project reportincident.persistence, we will replace our pom.xml file with the one provided in the zip file. As you can see in the <Import-Package>, we will import here the class required by the service : org.apache.camel.example.reportincident.dao Adding this line in the Import-Package is not enough to have access to the OSGI service. The file spring-service-beans-dao.xml must be modified to have a reference to this interface through the osgi:reference namespace :
...
<property name="incidentDAO">
<osgi:reference interface="org.apache.camel.example.reportincident.dao.IncidentDAO"/>
</property>
...
This reference will be used to call the osgi service to find the service corresponding to the interface name declared. If a match occurs, then a spring bean reference is created in the bundle reportincident.service. To expose our service as an OSGI service, we will create the file service-osgi.xml in the directory src/main/resources/META-INF/spring and add the 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" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <osgi:service ref="incidentService" interface="org.apache.camel.example.reportincident.service.IncidentService"/> </beans> Remark :
Step 4 : reportincident.webserviceThis bundle will not be exported as an OSGI service. So, we only need to modify the content of <Export-Package> to export the classes generated by the wsl2java maven plugin and the wsdl file :
<Export-Package>
org.apache.camel.example.reportincident,
'=META-INF.wsdl'
</Export-Package>
ConclusionNow that we have transformed our current project in bundles, it is time to design the routing and web parts of the application. In the next part of the tutorial, we will specify modification to do for the new incoming projects/bundles Links
Resources |