...
To convert a project into a bundle that you will be able to deploy into an OSGI server, a couple of things/steps must be done :
1) Declare the project in the maven pom.xml file as of type <packaging>bundle</packaging>,
2) Add the maven felix plugin who will generate the MANIFEST.MF file,
3) Identify the packages to be imported/exported and version,
4) Register Identify and register OSGI services when they are used by another bundle.
Tip |
---|
...
Spring team has created the Spring Dynamic Modules project to facilitate the work of the developer working with OSGI specification. It allows to transform existing spring beans (interface + implemented class) into OSGI services reachable by any bundle deployed. In fact the services are declared in a repository under the form of interfaces. This mechanism is known now as blueprint services or RFC 124 and is currently integrated under the OSGI specification R4.2. |
Step 1
...
: reportincident.model
To 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 the comment <!- STEP ->XML comment with word STEP
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.model</artifactId> <!-- STEP 1 --> <packaging>bundle</packaging> <name>Report Incident Model Bundle</name> <version>1.0-SNAPSHOT</version> <properties> <felix-version>1.4.3</felix-version> <camel-version>2.0-M1</camel-version> <commons-lang>2.4</commons-lang> </properties><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> |
...
Code Block |
---|
mvn clean install org.ops4j:maven-pax-plugin:eclipse |
Tip |
---|
...
the goal org.ops4j:maven-pax-plugin:eclipse is added to refresh the MANIFEST.MF file created |
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
...
It is time to continue with the persistence project where we will introduce new important concepts
Step 2
...
: reportincident.persistence
First, 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 , we would like to export only the interface to another 'service' bundles and keep internally the implementation.
Code Block | ||||
---|---|---|---|---|
| ||||
<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 :
Code Block | ||||
---|---|---|---|---|
| ||||
<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> |
...
Create the file persistence-osgi.xml
in the directory src/main/resources/META-INF/spring
and add the lines :
Code Block | ||||
---|---|---|---|---|
| ||||
<?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> |
...
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. A minimal declaration looks as follows:
So, we can adapt our spring-datasource-beans.xml
file created in the previous chapter with new xml tags :
Code Block |
---|
<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 data.source.office.1 entry org.apache.camel.example.reportincident.datasource
entry (2) as a bean named ds.cfgpreProps. Moreover, we will create 'for the deployment' a file 'the property declared (3) can be override by creating a file named org.apache.camel.example.reportincident
.datasource.cfg' that the OSGI registry service will use to instantiate the preporties.datasource.cfg
and containing the parameters :
Code Block |
---|
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 :
...
- We will see in the chapter 'deployment' where this file must be deployed.
- In our example, we have only defined
properties
for thedriver
,username
and {{password }} but you can extend the list of values with by example Hibernate parameters like hibernate.show_sql, hibernate.format_sql, ...
Step 3
...
: reportincident.service
Like 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 :
Code Block | ||||
---|---|---|---|---|
| ||||
... <property name="incidentDAO"> <osgi:reference interface="org.apache.camel.example.reportincident.dao.IncidentDAO"/> </property> ... |
...
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.
Code Block | ||||
---|---|---|---|---|
| ||||
<?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 :
- Transaction Management has been defined in the corresponding files of reportincident.persistence and reportincident.service but we will not discuss them in detail in this tutorial.
Step 4
...
: reportincident.webservice
This 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 :
Code Block | ||||
---|---|---|---|---|
| ||||
<Export-Package> org.apache.camel.example.reportincident, '=META-INF.wsdl' </Export-Package> |
Routing/Mediation service
The routing/mediation between services/bundles will be created using Spring DSL language.
Links
...
Conclusion
Now 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
...
...
- 2a : transform projects in bundles
- Part
...
...
#Resources
Attachments patterns .*part2.zip