Microservices with Apache Karaf and
Apache CXF: practical experience
Andrei Shakirin, Talend
Agenda
• Microservices and OSGi
• Core ideas of OSGi
• Apache Karaf
• Design and develop in OSGi: the history of one
project
• Conclusions and lessons learned
About Me
• Software architect in Talend Team
• PMC in Apache CXF
• Contributions in Apache Syncope, Apache
Aries and Apache Karaf
Microservices
(James Lewis and Martin Fowler)
• Application as suite of small services
• Organization around business capabilities
• Each service runs in own process
• Smart endpoints and dumb pipes
• Decentralized data management and
technologies
• Infrastructure automation
Microservices: Pros and Cons
Benefits:
• Services themselves are simple, focusing on doing
one thing well
• Systems are loosely coupled
• Services and can be (relatively) independently
developed and deployed by different teams
• Services can be scaled differently
• Service team can use the most appropriate
technologies and programming languages
Microservices: Pros and Cons
Downsides:
• Mistakes in services boundaries definition are costly
• Remote calls are expensive and unreliable
• Testing, debugging and monitoring in distributed system
became more difficult
• Change syntax or semantic of remote contracts
introduces additional risks
• Infrastructure becomes more complex
• Eventual consistency
OSGi => Modular Applications
What is the module?
OSGi: Modules and Modularity
OSGi: Modules and Modularity
OSGi: software modules
• Implements a specific function
• Can be used alone or combined with others
• Provides functionality to be reused or replaced
• Has well defined name
• Has a version
jars modules
OSGi: software modules
But:
• It is hard to achieve loosely coupling between the
modules (only partial solutions: Class.forName;
ServiceLoader; log-appenders)
• You cannot encapsulate functionality in the module
• Missing runtime control which version of the
dependencies functionality will be used
• Self-describing module contract is missing
• Keep the name and version of JAR file
• Add explicit package dependencies
OSGi bundle
(requirements)
• Add explicit package exports (capabilities)
• Provide API as external contract (OSGi services)
OSGi Services
• Service Contract is one or more java interfaces
• Bundle can register the service in registry
• Other bundle can get and listen for the service
• Multiple registered services can be distinguished using properties
• No any coupling between bundles except Service Contract:
neither in code, no on the classpath (different to java
ServiceLoader)
OSGi Decoupling
ActiveMQ Bundle MyAsyncCommunication Bundle
Exports: Imports:
org.apache.activemq.pool 5.14.0, org.apache.activemq.pool [5.14,6),
org.apache.activemq.command 5.14.0 org.apache.activemq.command [5.14,6)
Decoupling
JMS Communication
MyBusinessDomain Bundle Implementation
Imports: my.connector.async [1.0,2) Exports: my.connector.async
1.0.0
Import Service: Export Services
my.connector.async.Sender, Implementations:
my.connector.async.Listener my.connector.async.Sender,
my.connector.async.Listener
OSGi Decoupling
Article API Bundle Article Logic Bundle
Exports: my.domain.article 1.1.0
(my.domain.article.Availability interface) Imports: my.domain.article
[1.0,2) Availabilit
yDAO
Bundle
Availabilty Logic
Implementation
MyCartService Bundle SAP
Connector
Imports: my.domain.article [1.0,2) Decoupling Bundle
Import Service: Export Service Implementation:
my.domain.article.Availability my.domain.article.Availability
Declare OSGi Services: Option 1
• Declarative Services
Christian Schneider Blog: “Apache Karaf Tutorial part 10 - Declarative
services”
Declare OSGi Services: Option 2
• Blueprint
Classic Microservices vs OSGi
Aspect Microservices OSGi
Application structure Suite of small services Suite of bundles /
modules
Boundaries Around business Modularization around
capabilities business and technical
aspects
Communication Lightweight remote Flexible: local or remote
Contract Remote API Local java interfaces or
remote API
Decentralized Data Desired Depends on
Management requirements for single
process, desired for
multiple processes
Infrastructure Desired Desired
Automation
Apache Karaf
• OSGi based Container using Apache Felix or Eclipse
Equinox implementations
• Runs as Container, Docker Image, embedding (karaf-boot)
• Provisioning (maven repository, file, http, …)
• Configuration
• Console
• Logging, Management, Security
Karaf Features
mvn:my.company/order-service-features/1.0.0/xml
Maven Repo /
Nexus
Karaf
org.apache.karaf.features.cfg
featuresRepositories=…, mvn:my.company/order-service-features/
1.0.0/xml
featuresBoot= …, order-service
console
feature:addurl mvn:my.company/order-service-features/1.0.0/xml
feature:install order-service
Migration to OSGi in eCommerce Project
• Business Domain: WebShop, eCommerce
• Team: 20 – 30 persons
• Initial technologies: Java, Spring, Hibernate, Apache CXF,
Apache Camel, ActiveMQ, Tomcat
• Current technologies: Java, Hibernate, Apache CXF,
ActiveMQ, OSGi + Apache Karaf, SpringBoot, MongoDB
Online Shop Architecture
Web Browser
External consumers Frontend Mobile App
Online Finance REST
System
Active
Middleware MQ
Credit-Worthiness
Check System
SAP Oracle DB
Online Shop Design
REST REST REST REST
User Service Cart Service Article Service Order Service
Customer Domain Article Domain Order Domain
Core Domain
DAOs
SAP
Messaging
DB DB DB
Online Shop Design
REST REST REST REST
User Service Cart Service Article Service Order Service
Customer Domain Article Domain Order Domain
Core Domain
DAOs
SAP
Messaging
DB DB DB
Step 1: Packages Refactoring
com.mycompany com.mycompany
.domain.user .domain.user
.routes .account
.processors
.password
.converters
.mappers .deliveryaddress
.exceptions .billingaddress
• Classes for business function are grouped together -> high cohesion
• Less dependencies between packages -> low coupling
• Private and public packages are easily recognizable (model, api,
impl)
Christian Schneider ApacheCon Europe 2014 “Reflection of Design of Business Applications”
Step 2: Connectors API
REST REST REST REST
User Service Cart Service Article Service Order Service
Customer Domain Article Domain Order Domain
Core Domain
API: OSGI Svc API: OSGI Svc API: OSGI Svc API: OSGI Services API: OSGI Services
DB Connector DB Connector DB Connector SAP Connector Messaging Connector
SAP
ActiveMQ
DB DB DB
Step 3: Parallel Web And OSGi Deployment
Web Application
Module Code
WAR
OSGi
Features
resources
spring
OSGI-INF/blueprint
<packaging>bundle</packaging>
…
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</
artifactId>
</plugin>
Step 4: Refactor Complex Domain Logic (Camel Routes)
from(„vm:PriceAndAvailability“) PriceAndAvailResult getPriceAndAvail (Cart cart,
1
.bean(availabilityOptionsMapper) AvailabilityOptions options);
.multicast(hdrAggregationStrategy
)
ATPOptions atpOptions = mapAvailabilityOptions(options);
.parallelProcessing().timeout(100) …
.to(„direct:getPrice“) final Future<AvailabilityReturner> availabilityFuture =
executorService.submit(availabilityTask);
.to („direct:getAvailability“) 2 final Future<PriceReturner> priceFuture =
.end executorService.submit(priceTask);
.validate(availabilityValidator) …
validateAvailability(availability);
.bean(priceAvailResponseMapper) PriceAndAvailResult result = new
PriceAndAvailabilityResult(availability,
price);
• What type of data is • Type safe interfaces
transmitted? • Clearly shows what data is proceed
• Debug me ☺ • Not essentially verbose as Camel route
• Would it be harder in plain • Easy to debug and understand for team
Java?
Christian Schneider ApacheCon Europe 2014 “Reflection of Design of Business Applications”
Step 4: Domains APIs And Refactoring
REST REST REST REST
User Service Cart Service Article Service Order Service
Customer API: OSGI Domain
Services Article API; API: OSGI Services Order API; API: OSGI Services
Customer Domain
Order Domain
API; Domain Domain Article Domain Logic
Model Logic Model Model Logic
API: OSGI Svc API: OSGI Services API: OSGI Svc API: OSGI Svc API: OSGI Services
DB Connector SAP Connector DB Connector DB Connector Messaging Connector
SAP
DB DB DB ActibeMQ
Step 5: Separate containers for some services
RE RE
ST ST
Container Middleware Container Event
REST REST REST RE
ST
User Service Cart Service Event Service
Container Article
REST REST REST
Checkout Article
Order Service Service
Service
async Messaging
REST REST
Newsletter
Address Service
Service Messaging
async
SAP
Messaging
DB DB
REST Communication in OSGi
• DOSGi and Aries Remote Service Admin (RSA)
Christian Schneider “Lean Microservices on OSGi“, ApacheCon EU 2016
• Explicit via CXF
Design For Failure With Hystrix(Netflix)
Resilience With Hystrix
Resilience With Hystrix
Conclusions and Lessons Learned
• Design your application modular (either in OSGi or not)
• Care about decoupling between modules, high cohesion
inside the module and modules dependencies
• Continuously refactor your modules to achive optimal
boundaries
• Stay on single process at the beginning, split application
into different processes only if it is required and brings
benefits
• Define your remote and async APIs carefully, design
remote calls for failure
OSGi Critic and Myths
OSGi is complex: in understanding, in build, in deployment
and in debugging and has poor tooling support
The most understandable specification in the world (inclusive HTTP,
ConfigAdmin, DS, RSA, JTA, JMX, JPA)
<packaging>bundle</packaging>
…
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
Features, configuration, security, console
OSGi Critic and Myths
OSGi Critic and Myths
OSGi is not supported by frameworks and libraries
OSGi Critic and Myths
OSGi is not supported by frameworks and libraries
OSGi Critic and Myths
The most important OSGi feature is hot updates: install, delete or
replace the bundle on the fly
Yes, OSGi is designed for updates without restarting the whole
application, but:
1. Normally it is safer to restart the whole Container to have
reproducible state in production
2. Hot deployment is not a free lunch: application have to be
designed and tested for that
3. The main OSGi gain is not a hot deployment, but clean modular
application design, isolation and decoupling of modules. Hot
deployment is more derivative feature
4. Can be useful in developer environment, special use cases, partly
restarts
REST Communication in OSGi
• Consider REST Architectural Style principles (resources
design, verbs contracts, response codes, statelessness)
• Reuse CXF providers, features and interceptors (logging,
security)
• Customize (if necessary) through own JAX-RS Filters and
Interceptors, MessageBodyReaders and Writers,
ParamConverters, CXF Interceptors
• Consider to use Swagger to document and test your API
• Make your external calls resilient
OSGi Decoupling
Hibersap Bundle MySapFacade Bundle
Exports: org.hibersap, Exports: org.hibersap,
org.hibersap.execustion.jco, org.hibersap.execustion.jco,
org.hibersap.mapping.model org.hibersap.mapping.model
Decoupling
SAP JCO Communication
MyBusinessDomain Bundle Implementation
Imports: my.connector.sap Exports: my.connector.sap
Import Service: Export Service Implementation:
my.connector.sap.OrderExport my.connector.sap.OrderExport
Karaf Deployment
Configured as Jenkins JOBs with folwoing steps:
1. Stop Karaf Instance
2. Replace org.apache.karaf.features.cfg
3. Start Karaf Instance
4. Waiting for AvailabilityService
System Environments
Integration Consolidation Production
LB LB
Developer Tests • QA
Production
• Performance
tests
• Load tests
Swagger in JAXRS API
Swagger in JAXRS API: Java First
Swagger in JAXRS API: WADL First