Apache CXF CDI in Karaf (Using CXF and CDI 1.1 (JSR-346))
Apache CXF CDI + Apache Karaf
We are going to follow the following specs to create CXF application in Karaf
Jaxrs Spec - JSR-339
Jaxrs Spec - JSR-339
CDI 1.1 (JSR-346)
Create an Rest API and Implement the Rest Service Provider for the Same.
Expose the feature with feature:install cxf-jaxrs-cdi supported in Apache Karaf.
osgi-example-rest.api
Rest Api will
Pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>osgi.example</groupId>
<artifactId>osgi-example-rest</artifactId>
<version>1.0</version>
</parent>
<artifactId>osgi-example-rest.api</artifactId>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- **** -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.2.2</version>
<executions>
<execution>
<id>frontends</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.parent.parent.basedir}/swagger/v1/INDEX-frontends.yaml</inputSpec>
<language>com.utils.JavaCXFServerCodegenCustom</language>
<configOptions>
<modelPackage>osgi.example.model</modelPackage>
<apiPackage>osgi.example.api</apiPackage>
<invokerPackage>com.test.rest.invoker</invokerPackage>
<output>${project.basedir}/target/generated-sources</output>
</configOptions>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.utils</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>swagger-custom-codegen</artifactId>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/swagger/src/gen/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>io.swagger</groupId>
<artifactId>
swagger-codegen-maven-plugin
</artifactId>
<versionRange>
[2.2.2,)
</versionRange>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
REST API
package com.rest.api;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
@Path("/")
public interface PersonService {
@GET
@Path("/features")
@Produces("application/xml")
public Response getAll();
}
META-INF/beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
bnd.bnd
Bundle-Name: Rest API
-dsannotations: *
osgi-example-rest.provider
pom.xml
In order for the bundle to be recognized as web CDI one and use Apache CXF CDI capabilities, it should provide special bundle manifest instructions (f.e. by using maven-bundle-plugin plugin).
</instructions>
...
<Import-Package>
javax.servlet;version="[2.6,4)",
org.apache.cxf.jaxrs;version="[3.1,4)",
org.apache.cxf.cdi;version="[3.1,4)",
*
</Import-Package>
<Require-Capability>
org.ops4j.pax.cdi.extension; filter:="(&(extension=cxf-integration-cdi))",
osgi.extender; filter:="(osgi.extender=pax.cdi)"
</Require-Capability>
<Web-ContextPath>...</Web-ContextPath>
<_wab>src/main/webapp</_wab>
</instructions>
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>osgi.example</groupId>
<artifactId>osgi-example-rest</artifactId>
<version>1.0</version>
</parent>
<artifactId>osgi-example-rest.provider</artifactId>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>2.12.2</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>org.apache.karaf.features.core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>osgi.example</groupId>
<artifactId>osgi-example-rest.api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>osgi.example</groupId>
<artifactId>osgi-example-osgi.api</artifactId>
<version>1.0</version>
</dependency>
<!-- Dependency Management for PicketLink and Apache Deltaspike. <dependency>
<groupId>org.picketlink</groupId> <artifactId>picketlink-javaee-6.0</artifactId>
<version>2.7.1.Final</version> <type>pom</type> </dependency> <dependency>
<groupId>org.picketlink</groupId> <artifactId>picketlink</artifactId> <version>2.7.1.Final</version>
<scope>compile</scope> </dependency> -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-integration-cdi</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<obrRepository>NONE</obrRepository>
<instructions>
<Import-Package>
javax.servlet;version="[2.6,4)",
org.apache.cxf.jaxrs;version="[3.1,11)",
org.apache.cxf.cdi;version="[3.1,11)",
*
</Import-Package>
<Require-Capability>
org.ops4j.pax.cdi.extension;
filter:="(&(extension=cxf-integration-cdi))",
osgi.extender;
filter:="(osgi.extender=pax.cdi)"
osgi.extender;
filter:="(osgi.extender=pax.cdi)",
org.ops4j.pax.cdi.extension;
filter:="(extension=pax-cdi-extension)"
</Require-Capability>
<Web-ContextPath>...</Web-ContextPath>
<_wab>src/main/webapp</_wab>
<_dsannotations>*</_dsannotations>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
META-INF/beans.xml
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_1.xsd"
version="1.1">
<scan>
<exclude name="org.apache.cxf.**" />
</scan>
</beans>
Application Path Registration
package com.rest.service;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import com.interceptors.in.SecurityInterceptorIn;
import com.rest.features.MainFeature;
@ApplicationPath("/hello")
public class JaxRsApiApplication extends Application {
@Inject
private PersonServiceImpl personServiceImpl;
@Override
public Set<Object> getSingletons() {
return new HashSet<Object>(Arrays.asList(personServiceImpl));
}
}
Rest Service Implementation
Implementation the service and Inject the OSGI created in the Previous post
OSGI Service
package com.rest.service;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.Response;
import org.ops4j.pax.cdi.api.OsgiService;
import com.osgi.api.HelloService;
import com.rest.api.PersonService;
import com.rest.interceptor.Log;
@ApplicationScoped
@Named
public class PersonServiceImpl implements PersonService {
@Inject
@OsgiService
HelloService helloService;
@Override
@Log
public Response getAll() {
Response response = Response.ok("<recipe2>"+helloService.sayHello("Athish")+"</recipe2>").status(200).build();
return response;
}
}
bnd.bnd
Bundle-Name: OSGI Rest IMPL
-dsannotations: *
Karaf-Commands: *
Export-Package: \
com.osgi.api;uses:=org.apache.bar
Import-Package: \
javax.enterprise.*;version=1.0,\
*,\
org.apache.cxf.cdi
Project Structure look like this
Rest API
Rest Impl Provider
Deploying in Apache Karaf
Installing Features
PAX CDI,PAX WELD , PAX CDI WEB WELD and CXF
feature:install cxf-jaxrs-cdi
cxf-jaxrs-cdi provide the CXF + Jaxrs exposing through CDI it uses WELD
Deploying the REST Application
install -s mvn:osgi.example/osgi-example-rest.api/1.0
install -s mvn:osgi.example/osgi-example-rest.provider/1.0
Test the Application
http://localhost:8181/cxf/hello/features
On the hitting the above URL we get the following Response XML
<recipe2>Hello, Athish</recipe2>
Comments
Post a Comment