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

<?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.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:="(&amp;(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:="(&amp;(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

Popular posts from this blog

Apache Karaf + Pax CDI OSGI Service

OSGI + PAX CDI + Drools + Karaf