OSGi In Anger - Tara Simpson
-
Upload
mfrancis -
Category
Technology
-
view
2.561 -
download
0
Transcript of OSGi In Anger - Tara Simpson
![Page 1: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/1.jpg)
OSGi In AngerA Case Study
![Page 2: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/2.jpg)
Aepona?
• Instil customer for 3 years
• Provider of products into Telco space
• Focus on ‘Network as a Service’
• Think abstractions over operator capabilities
![Page 3: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/3.jpg)
Telecom Web Services(In a Nutshell)
• SOAP/REST web services offering simplified APIs over SMS, MMS, Location, Conference Calling, etc
• Endpoints provisioned on a per-partner basis
• Endpoints backed by per-partner runtime policy enforcement
![Page 4: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/4.jpg)
And Much More
• Billing
• Reporting
• Alarms
• Fault Reporting
• System deployed with null implementations of optional features
![Page 5: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/5.jpg)
nodeA
OAM
SMS
Architecture
TLX
MMS
nodeB
OAM
MMS
TLX
SMS
container(i.e. JVM)
Portal(JBoss)
DEVKIT(Eclipse)
containergroup
![Page 6: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/6.jpg)
Container Groups
MMS MMS
Load Balancer
Container Group
![Page 7: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/7.jpg)
Runtime
• Equinox-based stack
• Initial bundles defined by config.ini
• Bundles can be remotely installed, uninstalled, activated, etc
• Managed by Eclipse RCP plug-in or command line (telnet & Command Provider)
![Page 8: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/8.jpg)
A Potted History
• Project started in late 2006
• Began life as Artix-based stack
• Fairly large, ~10000 unit tests
• Evolved to OSGi 2007
![Page 9: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/9.jpg)
The OAM
• Operations, Administration and Maintenance component spec’ed in 2007
• Used to create, delete, monitor & manage a multi-container (JVM) environment
• Two key requirements: (a) 99.999% uptime (b) ability to DYNAMICALLY install, uninstall and patch components
![Page 10: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/10.jpg)
A Leap of Faith
• But for the wrong(ish) reasons
• OAM provided compelling reason for OSGi
• OSGi chosen mainly because it enabled hot-deploys
• Not because of enforced modularity or service-oriented design
![Page 11: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/11.jpg)
Perceived Downside
• OSGi insists on everything being made ‘modular’
• But aren’t we already modular?
• Don’t we partition our software effectively?1000s of unit tests say we do!
![Page 12: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/12.jpg)
Umm..NO!
• In retrospect, system far from modular
• Layers not partitioned cleanly
• Code not open for extension
• Free-for-all on code base
![Page 13: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/13.jpg)
Life Before OSGi
• Single source tree
• Spring Configuration Hell
• Extensibility issues - PS work polluting core product
• Build issues
![Page 14: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/14.jpg)
Evolving to OSGi
• How do we develop? Tools?
• How do we build? Ant, Maven?
• What to do with Artix, Spring & Hibernate?
• How to modularise existing code stream?
• How much time ($) is this going to take?
• No prior OSGi experience
![Page 15: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/15.jpg)
Eclipse PDE
• OSGi is first class citizen
• Single project defines ‘target platform’
• Per-customer PSF (Team Project Set) files
• Export bundles directly to TWS
• We like PDE - but we don’t know any better!
![Page 16: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/16.jpg)
Ant Build
• build.xml copies projects into launcher-prescribed directory structure and then kicks off launcher
• Heavy use of Eclipse features
• Considerable effort migrating projects over, but minimal effort in maintaining
• 400+ projects, features, fragments
![Page 17: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/17.jpg)
Baby Steps
• No big bang
• Artix converted to single bundle
• Common code refactored into core bundle
• Services deployed as mega-bundles, built from single source tree
• Gradual migration to OSGi services
![Page 18: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/18.jpg)
Hibernate
• Used bnd to create hibernate bundle
• Used DynamicImport-Package: * to find all exported mapping files & pojos
• Added Antlr & all hibernate jar files to internal classpath
• Works, but less than ideal
![Page 19: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/19.jpg)
Spring DM
• Consistent programming model with existing Spring infrastructure/knowledge
• No issues with proxy-based approach
• Outside of core, only use Spring DM
• Inside core, mixture of Spring DM and direct OSGi, but only when necessary
![Page 20: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/20.jpg)
Early Mistakes
• Failed to appreciate beauty of whiteboard pattern: publish/subscribe really should be replaced with export/track
• Modules not delineated using OSGi services - services enable dynamism & enforce better design
• Forgetting to unget services
![Page 21: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/21.jpg)
Gradual Modularisation
• Services migrated one at a time
• Initially, layers broken into modules with public and private parts
• Eventually, modules refactored to be service oriented
• Code base significantly cleaner
![Page 22: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/22.jpg)
Service(e.g. SMS)
ISmsActivityFactory
Life Before OSGi
ParlayX
ISmsDaoSmsMessage
SmsActivity
ICallback
Adapter
Gateway/Network
* ALL PUBLIC
![Page 23: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/23.jpg)
Service(e.g. SMS)
Life With OSGi
ParlayX
SmsMessage
SmsActivity
ISmsSenderAdapter - public
Gateway
SmsSender
ISmsDaoISmsDaoISmsDaoAdapter - private
OSGi service POJO
![Page 24: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/24.jpg)
Note to Self
• OSGi did not make me this way!
• But it encouraged me to step back...
• And be even more clinical in my separations
![Page 25: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/25.jpg)
Reality Check
• Developers rarely have the good grace to hide implementation details!
• Developers who struggle with partitioning and layering will struggle even more with OSGi
• OSGi requires that you think more & be more disciplined
![Page 26: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/26.jpg)
Today
• Extensive use of services & properties
• Heavy use of Spring DM
• Moderate use of the OSGi API
• Little use of compendium services
![Page 27: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/27.jpg)
Design• Layered
• Service-Oriented
• Event-Driven
• Loosely-Coupled
• Dynamic/Modular!
Service(e.g. SMS)
core
WebService(e.g. SMS)
Adapter
OSGi services
OSGi services
Shared OSGi
services
![Page 28: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/28.jpg)
Overall Philosophy
• Avoid the API at all costs
• Necessarily complex and wonderfully subtle - e.g. returning null from a tracker
• Well documented but good practice hard to come by
• Hard to unit test - especially trackers
• Instead use Spring DM wherever possible
![Page 29: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/29.jpg)
Using the OSGi API
• Only 1 activator across 150 production bundles
• BundleContext injected via Spring DM BundleContextAware
• Primarily used to track & register services
• Also used to track bundles e.g. update property accessor when bundle installed, signal OAM when bundle fails to install
![Page 30: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/30.jpg)
Idiomatic OSGi
• What is good practice? A catalog of idioms/patterns would be useful, very useful
/** * Property accessor tracker that creates describer's associated * policy description based on properties extracted from exported * policy accessor service. Once created the service is immediately * 'untracked'. */ private class PropertyAccessorTracker implements ServiceTrackerCustomizer {
public Object addingService(final ServiceReference serviceReference) { final IPropertyAccessor propertyAccessor = (IPropertyAccessor) bundleContext.getService(serviceReference); policyDescription = createPolicyDescription(propertyAccessor); bundleContext.ungetService(serviceReference); debug("Created policy description ", policyDescription); return null; }
public void modifiedService(final ServiceReference serviceReference, final Object service) { // Do nothing }
public void removedService(final ServiceReference serviceReference, final Object service) { // Do nothing - no need for unget } }
![Page 31: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/31.jpg)
Fragments
• Used extensively to configure bundles in customer specific ways
• Used to house unit tests (10000+)
• One test fragment for every production bundle
• Fragments containing code cannot be unit tested. Therefore avoid.
![Page 32: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/32.jpg)
Testing
• Focus mostly on behavioural & interaction-based unit testing
• Unit tests live in fragments
• Dedicated team for end-to-end testing
• Many parts of API mockable, except for trackers. Grumble.
![Page 33: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/33.jpg)
Features
• Eclipse features describe pre-canned applications/features
• Parsed into config.ini files at build time
• Deployed under <install-dir>/conf/apps/<feature>/config.ini
• Each feature in conf/apps presented as a deployable application on front-end
![Page 34: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/34.jpg)
OSGi Services
• Modules (mostly) communicate through services
• Services enable ALL extension points
• Lower layers define and export interfaces; consumed by higher layers
• Lower layers define and track interfaces; implemented & exported by higher layers
![Page 35: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/35.jpg)
serviceweb service proxy
MethodInterceptorInvoker
IMethodInterceptorIMethodInterceptorIMethodInterceptor
Exported OSGi serviceWith service properties:order=1targetMethods=sendSms
Dynamic Method Interception
![Page 36: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/36.jpg)
IMethodInterceptorimport org.aopalliance.intercept.MethodInterceptor;
/** * Method interceptor that enables any bundle to intercept * a service invocation. Implementations of this interface * are expected to be exported as an OSGi, along with 2 * properties: * <ul> * <li>an 'order' property used to determine the order in which * exported interceptors are invoked compared to each other</li> * <li>an optional set of comma separated 'targetMethods' method * names defining the method(s) that the interceptor should be * applied to</li> * </ul> * * Typically implementations will extend {@link AbstractMethodInterceptor} * rather than implement this interface directly. * * @see AbstractMethodInterceptor */public interface IMethodInterceptor extends MethodInterceptor {}
![Page 37: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/37.jpg)
Canned Method Interceptors
• Address Normalisation: Enables white & black listing
• Group Address Resolution: Send to ‘group:abc’ => send to many
• Reporting: On every system transaction
![Page 38: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/38.jpg)
serviceweb service proxy
PolicyEnforcer
EnforceablePolicyEnforceablePolicyEnforceablePolicy
Created using IPolicyDescriber (an OSGi service)
Policy Enforcement
![Page 39: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/39.jpg)
Tracking Lists/** * Provider of policy descriptions ({@link PolicyDescription}s), derived * from their service policy description ({@link IPolicyDescriber}) * counterpart. */public class PolicyProvider implements IPolicyProvider {
private List<IPolicyDescriber> describers;
/** * Sets the list of policy describers being tracked. * The supplied list is expected to be a Spring-backed * list that automatically proxies and tracks the actual * policy describers. * @param describers a set of policy describers to be used */ @Required public void setPolicyDescribers(final List<IPolicyDescriber> describers) { this.describers = describers; } ...
<bean id="policyProvider" class="com.aepona.tws.core.policy.support.PolicyProvider"> <property name="policyDescribers" ref="policyDescribers" /> </bean> <osgi:list id="policyDescribers" interface="com.aepona.tws.core.policy.IPolicyDescriber" cardinality="0..N" />
![Page 40: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/40.jpg)
Mobile Originated Events
• How to publish asynchronous SMS notifications and delivery receipts to third party applications?
• More generally - how do we publish events from lower layers to higher layers?
![Page 41: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/41.jpg)
NetworkThird PartyApplication
Service
Mobile Originated Events
?
![Page 42: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/42.jpg)
Back to the Whiteboard
• Lower layer defines and tracks ‘publisher’ interface
• Higher layer implements and exports publisher
![Page 43: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/43.jpg)
Whiteboard
SmsNotificationPublisher
ISmsNotificationPublisherSmsNotificationHandler
<<implements>>
to TPA
from network
Exported as OSGi service
Tracks ISmsNotificationPublisher
![Page 44: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/44.jpg)
Lifecycle Events
• Web service endpoints come and go
• How do we inform interested parties of such events?
• They may need to stop ongoing transactions e.g. in the network layer
![Page 45: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/45.jpg)
OSGi as an Event Bus
• Whiteboard pattern pervades system
• Core defines and tracks ‘listener’ services
• Bundles implement and export listener implementations
• Layers are massively decoupled from one another
![Page 46: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/46.jpg)
Service Listener/** * Interface to be implemented classes interested in service events. * Any instance of a type that implements this interface and that is * exported as an OSGi service will be informed of service lifecycle * events. Events are fired <i>asynchronously</i> but sequentially. * <p> * Implementations should not tie up the invoking thread. In other * words the {@link #serviceChanged(ServiceEvent)} method should * return as quickly as possible. */public interface IServiceListener {
/** * Receives notification that a service lifecycle event * has occurred. * * @param serviceEvent the service event */ void serviceChanged(ServiceEvent serviceEvent);}
![Page 47: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/47.jpg)
Service Event/** * A service event describing a service lifecycle change. * Service events are categorized as: * <pre> * create - signals that a service has been provisioned * update - signals that a service has been updated * dispose - signals that a service has been disposed * destroy - signals that a service has been destroyed * </pre> * An 'update' event signals that a service has been updated * without having to recreate the endpoint from scratch. * If an update requires that a service is re-provisioned * (because its service name has changed), then a 'destroy' * followed by a 'create' event will be emitted. */public final class ServiceEvent {
/** * Returns a service create event. * @param serviceName the newly created service name * @return a create service event */ public static ServiceEvent createEvent(final ServiceName serviceName) { return new ServiceEvent(CREATE, serviceName); }...
![Page 48: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/48.jpg)
Handling Service Events/** * Purges expired location notification requests from the system. * An expired notification is one that has sent the maximum number * of notifications or has reached its duration limit - both limits * are specified when the notification is created. */public class LocationNotificationTerminator implements ILocationNotificationTerminator, IServiceListener, InitializingBean, DisposableBean {
private ILocationNotificationCriteriaDao criteriaDao;
/** * Deletes data associated with a destroyed service */ public void serviceChanged(final ServiceEvent serviceEvent) { if (serviceEvent.isDestroyEvent()) { logger.debug("Stopping all notifications for " + serviceEvent.getServiceName()); stopAll(criteriaDao.findByServiceName(serviceEvent.getServiceName())); } }...
![Page 49: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/49.jpg)
Service Adapters
• When deployed inside operator TWS talks to single CORBA-based adapter
• When deployed outside operator TWS proxies onto multiple operator APIs
• Goal is unified API - OneAPI
• Each operator has own service adapter OSGi service
![Page 50: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/50.jpg)
OneAPI WebService
Service
IServiceAdapter
IServiceAdapter
IServiceAdapter
Exported as OSGi ServiceWith ‘name’ property name=orange
Service Adapters
sprint
vodafone
orange
• Need to support new operator, simply drop new adapter bundle
![Page 51: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/51.jpg)
Modularity Matters
• TWS is large - without OSGi it would, right now, be a mess
• Modularity enforces better discipline
• Modular designs are more extensible
• Modular designs are easier to test
• Modular designs are cheaper
![Page 52: OSGi In Anger - Tara Simpson](https://reader035.fdocuments.net/reader035/viewer/2022062405/5565cb14d8b42a8a7b8b4a4f/html5/thumbnails/52.jpg)
Personal Opinion
• First I couldn’t live without Design By Contract
• Then I couldn’t live without BDD & DI
• Now I dread life without OSGi
• Enforced modularity and OSGi services are indispensable design tools