Want to know how to design, implement and deploy modular enterprise integration solutions using OSGi? The Apache Karaf OSGi shell, used by Apache Felix and Apache ServiceMix, enhances core OSGi implementations like Felix or Equinox with an easy to use, extendible command shell, providing logging, hot deployment, configuration, container administration, clustering, high availability and easy 'feature-based' dependency management In this session, you'll learn how Karaf works, and how you can leverage Karaf either on its own or embedded within ServiceMix to deploy business logic, RESTful services, EIP-based integration flows and web services. You'll learn how to extend the command shell with your own commands, and, use Spring-DM *or* OSGi BluePrint Services to make using OSGi a walk in the park.
Nell’iperspazio con Rocket: il Framework Web di Rust!
OSGi for real in the enterprise: Apache Karaf - NLJUG J-FALL 2010
1. A
Progress
So*ware
Company
OSGi for real in enterprise integration
with Apache Karaf
Dr. Adrian Trenaman, Sr. Principal Solution Architect,
FuseSource
trenaman@fusesource.com
twitter: adrian_trenaman | linked-in adrian.trenaman
http://trenaman.blogspot.com http://slideshare.net/trenaman
2. A
Progress
So*ware
Company
Adrian Trenaman - credentials
•15 years IT consulting experience
- IONA Technologies, Progress
Software Corp, FuseSource
- SOA, ESB, Open Source, BPM,
Web Services, CORBA, …
- Solution focused: architecting,
mentoring, speaking, engineering,
doing…
• Committer, Apache Karaf
• PhD Artificial Intelligence, Dip.
Business Development
Ade’s consultancy map
3. A
Progress
So*ware
Company
Why are people adopting OSGi for
enterprise integration?
• Lead to the stream by ServiceMix, Karaf and other OSGi-based runtimes.
• ‘Green’ programming - reduce, reuse, recycle
– Reduce - the amount of code you write and deploy
– Reuse (modularity) -
• Separation of interface from implementation
• Versioning and multi-generational cohabitation
• Explicit dependency resolution - fail early, fail loud.
– Recycle - use existing legacy code if possible
• Agile deployment
– Dynamic deployment and hot redeploy
– Smaller artifacts
4. A
Progress
So*ware
Company
Motivating example
<<karaf>>
:ServiceMix
<<cxf-bundle>>
customer-rest
<<cxf-bundle>>
customer-soap-ws
<<camel-bundle>>
customer-batch-eip
<<blueprint-bundle>>
customer-logic
<<pojo>>
CustomerService
<<bundle>>
customer-jaxb
HTTP
SOAP/
HTTP
FILE
• Modular design
• Dynamic wiring
• POJO-driven
• Dependency Injection
• Standards based
class reuse
5. A
Progress
So*ware
Company
Aside: parsimonious, trim bundles…
• It’s so modular; no fat deployment artifacts!
• customer-batch-eip-1.0.0.jar - 5.5k
• customer-jaxb-1.0.0.jar - 4.4k
• customer-rest-1.0.0.jar - 4.9k
• customer-soap-ws-1.0.0.jar - 9.6k
• customer-logic-1.0.0.jar - 4.6k
6. A
Progress
So*ware
Company
Roadmap for this presentation
• Overview of Apache Karaf
• Discussion: Spring DM vs. Blueprint
• Implementing ‘motivating’ use-case
– OSGi POJO service
– RESTful, SOAP and EIP-based reuse of service
• Apache CXF JAX-RS
• Apache CXF JAX-WS
• Apache Camel
– Dynamic update of components
• Concluding thoughts
8. A
Progress
So*ware
Company
Apache Karaf
• A powerful OSGi-based container, originally ‘ServiceMix
Kernel’
– Supports Equinox and Felix OSGi runtimes
– Supports any component that can be wrapped as a jar file
(POJOs, HTTP servlets, Camel routes, JBI endpoints &
services, etc.)
• http://karaf.apache.org
Karaf
OSGI
Logging Deployment Provisioning Admin ConfigAdmin
Console
9. A
Progress
So*ware
Company
Apache Karaf - deployment
• Karaf hot-deploys any artifacts found in the deploy directory
– OSGi bundles (incl. Spring DM and OSGi Blueprint)
– Raw Spring/Blueprint files
– Karaf Archives (coming soon!)
• It provides additional deployment capabilities through different
URL handlers
– mvn: | file: | http: | wrap: | jbi: | etc...
• Extensible architecture means Karaf can support deployment
of different kinds of artifacts
– Used by ServiceMix 4 to deploy JBI artifacts
10. A
Progress
So*ware
Company
Apache Karaf - Deployment
• OSGi bundles
• JBI artifacts
• WARs
• Spring / Blueprint
XML configs
• Exploded archives
• Monitor
configuration files
11. A
Progress
So*ware
Company
Apache Karaf - logging
• The logging subsystem combines output from various loggers
to provide a standard OSGi Log service
– Based on OPS4j Pax Logging
(http://www.ops4j.org/projects/pax/logging)
– Supports API for Apache Commons Logging, SLF4J, Log4j, Java
Util Logging
– Combines all output into one synchronized log
– Uses Log4j configuration for easy management
• Karaf also provides a set of console commands to display,
view and change the log levels at runtime
12. A
Progress
So*ware
Company
Apache Karaf - Console
• The console provides a command line interface, with which
users can perform administrative tasks
• Commands take the form
{subshell}:{command} [options]
– A sub-shell is a group of related commands
– e.g. commands related to the OSGi framework begin with “osgi:”
• The console provides an SSH port for connecting to and
issuing commands in a remote instance of the kernel
– The ssh connection can be made secure
13. A
Progress
So*ware
Company
Apache Karaf - Configuration
• Configure bundles from multiple sources - properties files in
the /etc directory, JDBC, …
• Edit configuration values via the console
– These changes are propagated immediately to all bundles
• Can design bundles to dynamically detect configuration
changes and auto-reconfigure
• … all done through the OSGi ConfigAdmin service.
14. A
Progress
So*ware
Company
Modular deployment with
‘features’
• You can deploy almost anything into
Karaf
– War, Jar, bundle, spring, …
• Prefer OSGi bundles for your routing
/ integration / business logic
– More modular design, explicit
versioning, classpath control.
– Can share classes or objects
(OSGi services)
– Dynamic wiring of OSGi services
allows live hot deployment of
patches without impacting your
production deployment.
• Use the ‘feature’ mechanism to group
and co-deploy bundles.
<<jvm>>
:ServiceMix4
a:bundle
b:bundle
c:bundle
f1 f2
x:bundle
y:bundle
common
smx:> features:addUrl file:my-features.xml
smx:> features:install f1
my-features.xml
16. A
Progress
So*ware
Company
Spring DM and OSGi Blueprints
• Spring-DM is an OSGi extension to Spring
– First attempt at creating an easy dependency injection
programming model for OSGi.
– Now contributed to Eclipse (2009) as Gemini Blueprint project.
• ‘OSGi Blueprint’ is the standardized version of Spring-DM
– Implemented by Spring DM 2.x
– Apache Aries Blueprint used within Karaf
• Better support for namespace resolution and lifecycle
• Lightweight - smaller than Spring DM
17. A
Progress
So*ware
Company
Spring DM - Concept
<<karaf>>
META-INF/MANIFEST.MF
META-INF/spring/foo.xml
META-INF/spring/bar.xml
...
...
my-bundle.jar
All XML files in the META-
INF/spring directory are
interpreted as the same ‘Spring
Context’, and all beans are initiated
on bundle start and destroyed on
bundle stop.
18. A
Progress
So*ware
Company
OSGi Blueprint - concept
<<karaf>>
META-INF/MANIFEST.MF
OSGI-INF/blueprint/foo.xml
OSGI-INF/blueprint/bar.xml
...
...
my-bundle.jar
All XML files in the OSGI-
INF/blueprint directory are
interpreted as the same ‘Context’,
and all beans are initiated on bundle
start and destroyed on bundle stop.
20. A
Progress
So*ware
Company
POJO OSGi Service
public interface CustomerService {
Customer lookupCustomer(String customerId);
}
public class CustomerServiceImpl implements CustomerService {
public Customer lookupCustomer(String customerId) {
Customer c = new Customer();
c.setFirstName("Ade");
c.setLastName("Trenaman");
c.setPhoneNumber("+1234567890");
c.setId(customerId);
return c;
}
}
Blah.xml
21. A
Progress
So*ware
Company
POJO OSGi Service
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="customerServiceImpl"
class="com.fusesource.customer.impl.CustomerServiceImpl"
init-method="init" destroy-method="destroy">
<property name="dbUrl" value="somedb://" />
</bean>
<service ref="customerServiceImpl"
interface="com.fusesource.customer.CustomerService" />
</blueprint>
OSGI-INF/blueprint/customer-service.xml
22. A
Progress
So*ware
Company
‘bnd’ magic within Maven handles the
OSGi packaging…
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven-bundle-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>
com.fusesource.customer
</Export-Package>
<Private-Package>
com.fusesource.customer.impl
</Private-Package>
<Include-Resource>src/main/resources</Include-Resource>
</instructions>
</configuration>
</plugin>
pom.xml
24. A
Progress
So*ware
Company
Using a Karaf features file
<?xml version="1.0" encoding="UTF-8"?>
<features>
<!-- import other features files -->
<repository>mvn:org.apache.servicemix/apache-
servicemix/${servicemix.version}/xml/features</repository>
<feature name="customer-jaxb" version="1.0.0">
<bundle>mvn:${pom.groupId}/customer-jaxb/1.0.0</bundle>
</feature>
<feature name="customer-logic" version="1.0.0">
<feature version="1.0.0">customer-jaxb</feature>
<bundle>mvn:${pom.groupId}/customer-logic/1.0.0</bundle>
</feature>
. . .
</features>
src/main/filtere-resources/features.xml
25. A
Progress
So*ware
Company
• Use the features:addUrl command to register the features
file.
• Use the features:install / features:uninstall
commands to start and stop each feature.
26. A
Progress
So*ware
Company
Deploying REST and Web Services with
Apache CXF
27. A
Progress
So*ware
Company
REST Service
private static Logger logger
= LoggerFactory.getLogger(RESTfulCustomerService.class);
private CustomerService customerServiceLogic;
@GET
@Path("/customers/{id}/")
@Produces("application/xml")
public Customer getCustomer(@PathParam("id") String id) {
logger.info("Invoking getCustomer, Customer id is: " + id);
// Make use of the backend customer service logic!
//
return customerServiceLogic.lookupCustomer(id);
}
RESTfulCustomerService.java
28. A
Progress
So*ware
Company
REST Service
<jaxrs:server id="customerService"
address="http://0.0.0.0:8182/crm">
<jaxrs:serviceBeans>
<ref bean="customerSvc"/>
</jaxrs:serviceBeans>
</jaxrs:server>
<bean id="customerSvc"
class="com.fusesource.customer.rest.RESTfulCustomerService"
init-method="init" destroy-method="destroy">
<property name="customerServiceLogic" ref="customerLogic"/>
</bean>
<osgi:reference id="customerLogic"
interface="com.fusesource.customer.CustomerService"/>
META-INF/spring/customer-rest.xml
29. A
Progress
So*ware
Company
SOAP Service
@WebService(
targetNamespace =
"http://demo.fusesource.com/wsdl/CustomerService/",
portName = "SOAPOverHTTP",
serviceName = "CustomerService", name = "CustomerService"
)
public class CustomerServiceImpl implements CustomerService {
public LookupCustomerResponse lookupCustomer(LookupCustomer
parameters) {
// Invoke on the OSGi POJO
Customer customer =
customerServiceLogic.lookupCustomer(parameters.getCustomerId());
...
return response;
}
}
CustomerServiceImpl.java
30. A
Progress
So*ware
Company
SOAP Service
<jaxws:endpoint id="customerServiceJaxWSEndpoint"
implementor="#customerServiceImpl"
address="http://localhost:8083/soap/CustomerService"
/>
<bean id="customerServiceImpl"
class="com.fusesource.demo.soap.customer.CustomerServiceImpl">
<property name="customerServiceLogic" ref="customerLogic"/>
</bean>
<osgi:reference id="customerLogic”
interface="com.fusesource.customer.CustomerService"/>
META-INF/spring/customer-soap.xml
32. A
Progress
So*ware
Company
Camel Route
from("file:/tmp/customerIds")
.routeId("batchCustomerProcessor")
.split(body(String.class).tokenize("n"))
.to("bean:customerServiceLogic?method=lookupCustomer")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
Customer c = exchange.getIn().getBody(Customer.class);
logger.info("Processed customer " + c.getId() + ", name is "
+ c.getFirstName() + " " + c.getLastName());
}
});
CustomerBatchProcessor.java
33. A
Progress
So*ware
Company
Camel Route
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="batchProcessor" />
</camelContext>
<bean name="batchProcessor"
class="com.fusesource.demo.batch.customer.CustomerBatchProcessor"/>
<osgi:reference id="customerServiceLogic"
interface="com.fusesource.customer.CustomerService"/>
META-INF/spring/camel-route.xml
34. A
Progress
So*ware
Company
Summing up
• OSGi provides goodness in terms of modularity.
• Versioning, dependency management, classpath isolation, dynamic
wiring
• Apache Karaf augments core OSGi runtime with cross-
functional-concerns
• Logging, shell, configuration, security, …
• Karaf is a good home for Camel EIPs, CXF services…
• Apache ServiceMix pulls it all together.
• All the code from this presentation is available from the author!
35. A
Progress
So*ware
Company
OSGi for real in enterprise integration with
Apache Karaf
Dr. Adrian Trenaman, Sr. Principal Solution Architect,
FuseSource
trenaman@fusesource.com
twitter: adrian_trenaman | linked-in adrian.trenaman
http://trenaman.blogspot.com http://slideshare.net/trenaman