A Progress So*ware Company
OSGi for real in enterprise integrationwith Apache Karaf
Dr. Adrian Trenaman, Sr. Principal Solution Architect,FuseSource
[email protected]: adrian_trenaman | linked-in adrian.trenaman
http://trenaman.blogspot.com http://slideshare.net/trenaman
A Progress So*ware Company
Adrian Trenaman - credentials
•15 years IT consulting experience - IONA Technologies, ProgressSoftware 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
A Progress So*ware Company
Why are people adopting OSGi forenterprise 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
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
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
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
A Progress So*ware Company
Apache Karaf - an overview
A Progress So*ware Company
Apache Karaf
• A powerful OSGi-based container, originally ‘ServiceMixKernel’– 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 ConfigAdminConsole
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 differentURL handlers– mvn: | file: | http: | wrap: | jbi: | etc...
• Extensible architecture means Karaf can support deploymentof different kinds of artifacts– Used by ServiceMix 4 to deploy JBI artifacts
A Progress So*ware Company
Apache Karaf - Deployment
• OSGi bundles• JBI artifacts• WARs• Spring / Blueprint
XML configs• Exploded archives• Monitor
configuration files
A Progress So*ware Company
Apache Karaf - logging
• The logging subsystem combines output from various loggersto 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
A Progress So*ware Company
Apache Karaf - Console
• The console provides a command line interface, with whichusers 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 andissuing commands in a remote instance of the kernel– The ssh connection can be made secure
A Progress So*ware Company
Apache Karaf - Configuration
• Configure bundles from multiple sources - properties files inthe /etc directory, JDBC, …
• Edit configuration values via the console– These changes are propagated immediately to all bundles
• Can design bundles to dynamically detect configurationchanges and auto-reconfigure
• … all done through the OSGi ConfigAdmin service.
A Progress So*ware Company
Modular deployment with‘features’
• You can deploy almost anything intoKaraf– 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 ofpatches without impacting yourproduction deployment.
• Use the ‘feature’ mechanism to groupand 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
A Progress So*ware Company
Spring DM vs. OSGi Blueprint
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
A Progress So*ware Company
Spring DM - Concept
<<karaf>>META-INF/MANIFEST.MFMETA-INF/spring/foo.xmlMETA-INF/spring/bar.xml......
my-bundle.jar
All XML files in the META-INF/spring directory areinterpreted as the same ‘SpringContext’, and all beans are initiatedon bundle start and destroyed onbundle stop.
A Progress So*ware Company
OSGi Blueprint - concept
<<karaf>>META-INF/MANIFEST.MFOSGI-INF/blueprint/foo.xmlOSGI-INF/blueprint/bar.xml......
my-bundle.jar
All XML files in the OSGI-INF/blueprint directory areinterpreted as the same ‘Context’,and all beans are initiated on bundlestart and destroyed on bundle stop.
A Progress So*ware Company
Deploying POJO OSGi services
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
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
A Progress So*ware Company
‘bnd’ magic within Maven handles theOSGi 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
A Progress So*ware Company
Using a Karaf ‘features’ file to deploy
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
A Progress So*ware Company
• Use the features:addUrl command to register the featuresfile.
• Use the features:install / features:uninstallcommands to start and stop each feature.
A Progress So*ware Company
Deploying REST and Web Services withApache CXF
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
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
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(LookupCustomerparameters) {
// Invoke on the OSGi POJO Customer customer = customerServiceLogic.lookupCustomer(parameters.getCustomerId());
... return response; }}
CustomerServiceImpl.java
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
A Progress So*ware Company
Deploying EIP flows with Apache Camel
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
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
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!
A Progress So*ware Company
OSGi for real in enterprise integration withApache Karaf
Dr. Adrian Trenaman, Sr. Principal Solution Architect,FuseSource
[email protected]: adrian_trenaman | linked-in adrian.trenaman
http://trenaman.blogspot.com http://slideshare.net/trenaman