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