Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
Enterprise Application Development with OSGiat Statistics South Africa
Aslam KhanTechnical DirectorPBT [email protected]
Read my blog at http://aslamkhan.net
The Guy from Cape Town, South Africa
18+ years of application development experience
Waiting impatiently for admission to the 40+ geek club :-)
“Writing software is social exercise, not a technical one.”
What keeps me up at night?
What keeps me going?
Warning! British spell checker in use.
Wasting time,Conscientiously.Thou art that!
I am everything,I am nothing.
Time (minutes) Attention (brain cycles)
Enterprise Application Horror MoviesThe Return of the Class Loader• Back by popular demand, that old JAR that got in the way the last time
• and, starring, as the Joker, the ultimate villain ... the Java Class Loader
The Devil and Downtime• AKA “I still need what you did last summer”
• featuring projects that live forever
• and the roll out that never rolled back
Attack of the Killer Modules• starring vertical partitions,
• and horizontal layers
• and the omni-present, massively bloated, common-lib
A TSS-JS gift for your boss
I went to TSS-JS
and all Ilearnt was ...
OSGi is the Dynamic
Module System for Java
There is hope beyond
the regular Class Loader
POJO+OSGi+Spring-DM
rocks!
OSGi is very agile
There is an SOA lurking
in my app!
About Stats SA
Time (minutes) Attention (brain cycles)
Statistics South Africa
Their business is data!
It’s a production line for making data from data
When their domain is data ... • we model their data = metadata
When their domain switches to metadata• we model their metadata = para-data?
Rich in processes
Strong theoretical emphasis
Very academic organisation
Statistical Production Line
Need Design Build Collect Process Analyse Disseminate
Metadata
Process Management
Access Control and Confidentialization
CollectionsArea
Input DataArea
Output DataArea
DisseminationArea
Exploratory Analysis
Rough Inventory
About 15 facilities (sub-systems)
Between 30 and 40 applications
Between 10 and 20 databases
Many intersections between apps
Some deep hierarchical dependencies
Some hubs with joining spokes
It doesn’t matter if you can’t
read this!
The traditional approach
“Sure, we got layers ...”
“... and a shared core!”
Some problems
Long living project of about 3 years
Agile over 3 years ?• Of course we embrace change ;-)
Go live every 3 months
Complex domain space
Difficult to slice into vertical partitions
Diversity challenges
About OSGi
Time (minutes) Attention (brain cycles)
What is OSGiTM?OSGi - The dynamic module system for Java
It’s a specification
Lightweight, Java runtime for embedded systems
Currently at Release 4
Release 5 in progress
OSGi is all around youEclipse version 3.2 and above
IBM WebSphere
IBM Lotus Family
JOnAS Open Source EJB Container
Inside your BMW
Some familiar Open Source OSGi PlayersEclipse
Apache
SpringSource
Who controls the spec?OSGi Alliance• http://www.osgi.org
OSGi Enterprise Expert Group
The Obligatory OSGi pictureManaged ecosystem
Component Based
Dynamic
What is an OSGi bundle?It’s a JAR
... with OSGi manifest headers
... that provide versioning information package sharing dependencies native code
It’s peek-proof !!
Bundles have a life cycle!"#$%&'()$%!*'$+
! "#$%&'($%)*+,$%,-*$.%
/$('0$1%-0%234%(5.%6#$%
'016-,,-6'507%16-.67%
16587%98/-6$%-0/%
90'016-,,-6'50 5(%
:90/,$1
! ;90/,$%<-0-=$.%
>-0-=$1%6#$%8,-6(5.>
! ?$8$0/$0+'$1%-.$%
@$,,%>-0-=$/
!"#$%&&'(
)'#*&+'(
,"!"#$%&&'(
%-$!+'
#$*..!"/
#$%)$!"/
01231
0145
Sure, we have services !Dynamic discovery, binding and unbinding
Reusable, not coupling
Contracts and Implementations!"#$%&"'()*"#
! "#$%&%'#(')#(*+,'&%*'(
-&+.(')#(
/.$0#.#,'%'/+,1 200+34(%0'#&,%'#(
/.$0#.#,'%'/+,4
! 56,%./*%006(7/4*+8#&(
%,7(9/,7(%8%/0%90#(
/.$0#.#,'%'/+,4(1 :%4#7(+,(*+,'&%*'(
;/,'#&-%*#<
! =+.$+,#,'4(%&#(
&#>4%90#1 ?+'(*+>$0#7('+(
!"#$%&"'()*+#,&+
()-.)*"*+.#)$%/"0
10"0
2%0+"*0
SecurityPart of the fabric and not bolted on later
Enforceable permissions for clients
Dynamically managed using an API
OSGi 101So we know about OSGi ...
But the horror movies play on ...
!"#$%&"'()*"#
! "#$%&%'#(')#(*+,'&%*'(
-&+.(')#(
/.$0#.#,'%'/+,1 200+34(%0'#&,%'#(
/.$0#.#,'%'/+,4
! 56,%./*%006(7/4*+8#&(
%,7(9/,7(%8%/0%90#(
/.$0#.#,'%'/+,4(1 :%4#7(+,(*+,'&%*'(
;/,'#&-%*#<
! =+.$+,#,'4(%&#(
&#>4%90#1 ?+'(*+>$0#7('+(
!"#$%&"'()*+#,&+
()-.)*"*+.#)$%/"0
10"0
2%0+"*0
!"#$%&'()$%!*'$+
! "#$%&'($%)*+,$%,-*$.%
/$('0$1%-0%234%(5.%6#$%
'016-,,-6'507%16-.67%
16587%98/-6$%-0/%
90'016-,,-6'50 5(%
:90/,$1
! ;90/,$%<-0-=$.%
>-0-=$1%6#$%8,-6(5.>
! ?$8$0/$0+'$1%-.$%
@$,,%>-0-=$/
!"#$%&&'(
)'#*&+'(
,"!"#$%&&'(
%-$!+'
#$*..!"/
#$%)$!"/
01231
0145
Intro to Spring-DM
Time (minutes) Attention (brain cycles)
Horror Movie #1 The Attack of the Class Loader• Back by popular demand, that old JAR that got in the way the last time
• and, starring, as the Joker, the ultimate villain ... the Java Class Loader
It’s about ...• dynamic class management
• service binding
The opening scene ...• interface driven development
• life with POJO’s
What’s missingPOJO’s are great but ...• a managed POJO ecosystem will be really fantastic
OSGi is a managed ecosystem for POJO’s• And it is dynamic!
• And the class loader is the nice guy ... really!
• And it has a service registry!
Simple Example Contract
Implementation
What do we need?OSGi Run-time
What do we need?OSGi Run-time
Bundle 1: DataElement Bundle
DataElementService
DataElementServiceImpl
What do we need?OSGi Run-time
Bundle 2: SurveyMetadata Bundle
SurveyMetadata
SurveyMetadataImpl
Bundle 1: DataElement Bundle
DataElementService
DataElementServiceImpl
dependency
What are we going to do? OSGi Service Register
What are we going to do? OSGi Service Register
DataElementServiceActivator
What are we going to do? OSGi Service Register
DataElementServiceDataElementServiceActivator
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator1. registers
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator
SurveyMetadataActivator
1. registers
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator
SurveyMetadataActivator
1. registers
DataElementServiceTracker
2. creates
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator
SurveyMetadataActivator
1. registers
3. finds
DataElementServiceTracker
2. creates
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator
SurveyMetadata
SurveyMetadataActivator
1. registers
3. finds
DataElementServiceTracker
2. creates
4. binds
What are we going to do? OSGi Service Register
DataElementServiceDataElementService
Activator
SurveyMetadata
SurveyMetadataActivator
1. registers
3. finds
5. registerDataElementService
Tracker
2. creates
4. bindsbound!
Activate and Register the Dependencypublic class DataElementServiceActivator implements BundleActivator
{
private ServiceRegistration registration;// ...
public void start(BundleContext context) { DataElementService des = new DataElementServiceImpl(); Dictionary props = new Properties(); // ...
registration = context.registerService(DataElementService.class.getName(), des, props);
}
public void stop(BundleContext context) { registration.unregister(); }}
What are we going to do? OSGi Service Register
DataElementServiceDataElementServiceActivator
SurveyMetadata
SurveyMetadataActivator
1. registers
3. finds
5. registerDataElementService
Tracker
2. creates
4. bind
Activate the SurveyMetadata Bundlepublic class SurveyMetadataActivator implements BundleActivator {
private DataElementServiceTracker tracker;
public void start(BundleContext context) { tracker = new DataElementServiceTracker(context); tracker.open(); }
public void stop(BundleContext context) { tracker.close(); }}
What are we going to do? OSGi Service Register
DataElementServiceDataElementServiceActivator
SurveyMetadata
SurveyMetadataActivator
1. registers
3. finds
5. registerDataElementService
Tracker
2. creates
4. bind
Track Dependencies in the Service Registerpublic class DataElementServiceTracker extends ServiceTracker {
private SurveyMetadata surveyMetadata;// ...
public Object addingService(ServiceReference reference) { DataElementService des =
(DataElementService) context.getService(reference); surveyMetadata.setDataElementService(des);
synchronized (this) { // (track usage, cardinality, etc.) ... } ServiceRegistration reg = context.registerService(
SurveyMetadata.class.getName(), surveyMetadata, null); // ... return des; }
public void removedService(ServiceReference reference, Object service) { DataElementService des = (DataElementService) service; // decide how to handle the disappearing service... context.ungetService(reference); // ...
}
What are we going to do? OSGi Service Register
DataElementServiceDataElementServiceActivator
SurveyMetadata
SurveyMetadataActivator
1. registers
3. finds
5. registerDataElementService
Tracker
2. creates
4. bind
Simplify with Spring-DM <!-- Standard POJO instantiation -->
<bean name="dataElementService" class="statssa.DataElementServiceImpl" />
<!-- export POJO implementation to the OSGi service register --> <osgi:service id=”dataElementService” ref="dataElementService”
interface=” statssa.DataElementService”> <!-- Inject the dependency from the OSGi service register --> <bean name="surveyMetadata" class="statssa.SurveyMetadataImpl"> <property name="dataElementService"> <osgi:reference interface="statssa.DataElementService"/> </property> </bean>
<!-- export MyService to the OSGi service register --> <osgi:service ref="surveyMetadata"> <osgi:interfaces> <value>statssa.SurveyMetadata</value> </osgi:interfaces> </osgi:service>
Unit testing doesn’t change
Everything regarding the domain is still a POJO
Even without Spring-DM, OSGi glue is separated out
Vanilla unit testing is very achievable !
You can still test dependencies using mock objects !
Don’t forget that TDD is about writing code, not tests!
Integration testing your bundles
Spring-DM has a JUnit based Test class for OSGi
AbstractConfigurableBundleCreatorTests
• starts the OSGi framework (Equinox, Knopflerfish, Felix)
• install and start any specified bundles required for the test
• package the test case itself into an on the fly bundle, generate the manifest (if none is provided) and install it in the OSGi framework
• execute the test case inside the OSGi framework
• shut down the framework
• passes the test results back to the originating test case instance that is running outside of OSGi
Extract from the Spring-DM reference document ...
About Versioning
Time (minutes) Attention (brain cycles)
Horror Movie #2 The Devil and Downtime• AKA “I still need what you did last summer”
• featuring projects that live forever
• and the roll out that never rolled back
It’s about• class versioning
• backward compatibility
Make your JAR OSGi-aware # Indentification headers
Bundle-SymbolicName: org.sample.MyServiceBundle-Version: 1.0.1Bundle-Name: Sample ServiceBundle-Vendor: Samples, Inc.
# Class PathBundle-ClassPath: .
# Bundle Lifecycle managementBundle-Activator:org.sample.MyServiceActivator
# DependenciesImport-Package: org.osgi.framework;version=1.3Require-Bundle: org.sample.AnotherService;bundle-version=”[1.2.0,2.0.0)”
# ExportsExport-package: org.sample.MyService
POJO’s in the EcoSystemBinding on Version Numbers
Even tighter controlUsing Version and Custom Attributes
It’s all dynamic ... at run-time!
About Modularity
Time (minutes) Attention (brain cycles)
Horror Movie #3 Attack of the Killer Modules• starring vertical partitions,
• and horizontal layers
• and the omni-present, massively bloated, common-lib
It’s about• a really tricky problem
• design
The Typical Horizontal Layers
Data Access Objects
Domain Objects
Service Objects
Controller Objects
View Objects
Vertical Partitions and the Shared Common Lib
Cust
omer
s
Sale
s
Stoc
k
etc....
Common Lib
Vertical Partitions and the Shared Common Lib
Cust
omer
s
Sale
s
Stoc
k
etc....Common Lib
Reality Check?
..
Common Lib
Data Access Objects
Domain Objects
Service Objects
Controller Objects
View Objects
Data Access ObjectsDomain Objects
Service Objects
Controller Objects
View Objects
Sales
Stock
etc.
Common LibCustomers
..
Make Peace with DuplicityDuplicity at run-time is not a bad option
But ...
there must be no duplicity in source code
But ...
it still feels terrible
So ...
light a candle, meditate deeply and make peace with it :-)
Build Time AssembliesAfter inner peace ...
You still need ...• good code base structure
• probably a custom build tool
• maybe flatten your code base tree
• craft your own dependency resolver
Build Time Assemblies !
Using Domain Driven Design
Data Access ObjectsDomain Objects
Service Objects
Controller Objects
View Objects
Sales
Stock
etc.
Common Lib
Customers
..
Granularity of modules is up to youCoarse granularity (relatively speaking)• bounded contexts
• touch points between contexts
• transformations between contexts
Really fine granularity• Aggregates, Repositories, Factories, etc.
• Even though these are lifecycle patterns ...
Middle ground• DDD Modules tell stories
• Modules are cohesive ...
• and loosely coupled
Run-time AssembliesDDD can give us really good modules• at the granularity that you need
Because DDD is about practical designs• the granules are real!
• granule = OSGi Bundle!
• draw it, design it, OSGi-fy it and drop in, toss out ... at run-time!
• It will find what it needs to get the job done
Run-time Assemblies• OSGi is agile!
Refactoring and OSGiDon’t worry about it, we’ll just refactor it later ...• yeah, right :-(
Code refactoring is not too bad
Refactoring your code base structure is horrible!
With DDD, “module” refactoring is encouraged ...• and OSGi can run multiple versions of your modules ... (drum roll)
Don’t worry about it, we’ll just refactor it later !• YEAH! :-)
Wrap-up
Time (minutes) Attention (brain cycles)
OSGi 101
!"#$%&"'()*"#
! "#$%&%'#(')#(*+,'&%*'(
-&+.(')#(
/.$0#.#,'%'/+,1 200+34(%0'#&,%'#(
/.$0#.#,'%'/+,4
! 56,%./*%006(7/4*+8#&(
%,7(9/,7(%8%/0%90#(
/.$0#.#,'%'/+,4(1 :%4#7(+,(*+,'&%*'(
;/,'#&-%*#<
! =+.$+,#,'4(%&#(
&#>4%90#1 ?+'(*+>$0#7('+(
!"#$%&"'()*+#,&+
()-.)*"*+.#)$%/"0
10"0
2%0+"*0
!"#$%&'()$%!*'$+
! "#$%&'($%)*+,$%,-*$.%
/$('0$1%-0%234%(5.%6#$%
'016-,,-6'507%16-.67%
16587%98/-6$%-0/%
90'016-,,-6'50 5(%
:90/,$1
! ;90/,$%<-0-=$.%
>-0-=$1%6#$%8,-6(5.>
! ?$8$0/$0+'$1%-.$%
@$,,%>-0-=$/
!"#$%&&'(
)'#*&+'(
,"!"#$%&&'(
%-$!+'
#$*..!"/
#$%)$!"/
01231
0145
At Statistics SALarge suite of apps spanning a statistical production line
Impossible (?) without ...• DDD to give us modules
• Run Time Assemblies
• OSGi - The dynamic module system for Java
Where we are headingBuild time assemblies
Custom build tool
Aspects across bundles• Eclipse Equinox Aspects
Other interesting things• Object Database for Ontologies
• Java Content Repository
• JRuby based DSL for statistical metadata models
• Complex Event Processors / Analysers
OSGi is the Dynamic
Module System for Java
There is hope beyond
the Class Loader
POJO+OSGi+Spring-DM
rocks!
OSGi is very agile
There is an SOA lurking
in my app!
Some ResourcesOSGi Alliance http://www.osgi.org
Eclipse Equinox http://www.eclipse.org/equinox
Apache Felix http://felix.apache.org
Spring Framework http://www.springframework.org
Spring Dynamic Modules http://www.springframework.org/osgi
Eclipse Equinox Aspects http://www.eclipse.org/equinox/incubator/aspects/index.php
Domain Driven Design http://www.domaindrivendesign.org
Questions
Open Discussion+
Short Demo(time permitting)