Apache Karaf, CXF & Open API — Building integration components for REST utilizing OpenAPI specifications.

In this article, we’ll talk and work with the following technologies:

  • Apache Karaf / Talend ESB (Open Source Version)
  • REST, OpenAPI API Design (To generate cxf stubs)
  • Apache Camel (For Message Routing)
  • Apache CXF (API Runtime)
  • Blueprint

The Open API Specification

Open API is a advancement of Swagger and is used to both describe the API we’re building and also generating documentation. Additionally, there is a UI which lets you test your API during runtime. Many firms in the space have joined the Open API Initiative.

Using openapi-generator-maven-plugin to generate CXF Webservice stubs

The OpenAPI Tools generator can be utilized to generate CXF. You can embed the generator in your maven build process by using OpenAPI’s Maven Plugin:

<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
 <phase>validate</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${basedir}/src/main/resources/openapi/petstore.yaml</inputSpec>
<language>jaxrs-cxf</language>
<generateSupportingFiles>false</generateSupportingFiles>
<generateModelDocumentation>true</generateModelDocumentation>
<modelPackage>model</modelPackage>
<generateApis>true</generateApis>
<generateModels>true</generateModels>
<configOptions>
<sourceFolder>src/main/java</sourceFolder>
<java8>true</java8>
<dateLibrary>java8</dateLibrary>
<useBeanValidation>true</useBeanValidation>
<returnResponse>true</returnResponse>
<modelPackage>ch.aymenfurter.api.model</modelPackage>
<apiPackage>ch.aymenfurter.api</apiPackage>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>

Let’s have a look at the most important configuration options:

  • generateApis, generateModels
    generateApis controls if you want to produce CXF API Classes. You sadly can’t control if you only want to produce the interface classes, but that won’t be a problem in our use case, as Camel does not use the implementation class (but needs the interface class). For some target languages, there is an additional configOption called ‘interfacesOnly’, but after reviewing the implementation for CXF Stubs, it looks like this is not supported for CXF Stubs. generateModels is used to define if you want model classes to be created (Case Classes).
  • apiPackage / modelPackage
    These properties define what package names should be used for the generate API
  • language
    This configuration defines what kind of stubs you want the maven plugin to produce. In this example we’ll want the plugin to generate jax-rs cxf stubs.

Accessing Open API Specification during runtime

In a recent CXF Release (Version 3.2.5), support for OpenAPI Contracts was added to Apache CXF. This let’s you generate the Openapi JSON File during runtime by adding a feature to your endpoint specification:

<camel-cxf:rsServer id=”rsServer”
 address=”/petstore” serviceClass=”ch.aymenfurter.api.PetsApi”
 loggingFeatureEnabled=”true” loggingSizeLimit=”20">
 <camel-cxf:providers>
 <ref component-id=”jsonProvider” />
 <ref component-id=”multipartProvider” />
 </camel-cxf:providers>
 <camel-cxf:features>
<ref component-id=”openApiFeature” />
</camel-cxf:features>
 </camel-cxf:rsServer>

Testing your API

You can test your API both with SoapUI or Postman.

Building a mock endpoint

Let’s have a look at the blueprint implementation:

<camelContext trace=”false” id=”blueprintContext” xmlns=”http://camel.apache.org/schema/blueprint">
<route customId=”true” id=”cxfrs.service”>
<from uri=”cxfrs:bean:rsServer?bindingStyle=Default” />
<log message=”The message contains ${body[0]}” />
<marshal>
<json library=”Jackson” />
</marshal>
<process ref=”petProcessor” />
</route>
</camelContext>

Now we are able to build our integration logic utilising Enterprise Integration Patterns.

Running the Route

First of all you’ll need a local docker installation. I used the Open Source Version of Talend 7.1.1 for my testing, but you can also use “Vanilla” Karaf and add CXF > 3.2.5 repository

$ git clone https://github.com/aymenfurter/talend-docker.git
# Download TOS 7.1.1 and put it as ‘tos.zip’ into the talend-docker directory.
$ docker build . -t tos-beta

After building the TOS 7.1.1 Base Image, you now can build and start the TOS 7.1.1 Runtime like this:
$ git clone https://github.com/aymenfurter/openapi-cxf-osgi-mock
$ mvn clean package -DskipTests && docker build . -t intgr1 && docker run -p 8040:8040 -a stdin -a stdout -it intgr1
$ feature:install cxf-jaxrs cxf-rs-description-openapi-v3 cxf-jackson cxf-rs-description-swagger2 camel-jackson

You will see your service exposed on localhost: http://localhost:8040/services