Since we're on a major migration process of this website, some component documents here are out of sync right now. In the meantime you may want to look at the early version of the new website
https://camel.apache.org/staging/
We would very much like to receive any feedback on the new site, please join the discussion on the Camel user mailing list.
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>, 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.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 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 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 <Private-Package>org.apache.camel.example.reportincident.dao.impl</Private-Package> <Export-Package>org.apache.camel.example.reportincident.dao</Export-Package> Discovering all the classes used by a third party library like Hibernate can be cumbersome and takes time. An interesting alternative is to use the command 'DynamicImport-Package' to resolve classloading issue. <DynamicImport-Package> *</DynamicImport-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 <?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 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 <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 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///report username=root password= Spring using the 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 ... <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 <?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 |