About me
Born 1970,Started on a ZX81 in the early 80‘s
Doing a daytime job with JSF Frontend (leave that uncommented)
Developing a commercial book publisher‘s software with my own company Eiswind Software onOSGi, Spring, Hibernate, Eclipse RCP since 2007
Casual Eclipse and Apache project contributor (could you provide a patch ?)
Sometimes dreaming in code.
The scenario
• RCP Client talks to backend over HttpInvoker
• Server talks to client through XMPP
SynchronousRemote procedure calls
Asynchronous messaging(XMPP)
Client-Server compatibility
• Client and Server share domain classes and service interfaces
Client bundles
Server bundles
Shared bundles must be„wire compatible“
Definition of „wire compatible“
• OSGi versioning gives us
– major, minor, micro
– qualifier
• We defined that „wire compatible“ means major,minor and micro must match.
• Qualifier my change, shared bundles must be API compatible
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: Domain PluginBundle-SymbolicName: de.eiswind.mango.domainBundle-Version: 1.7.0.20101020
Uhh, we have customers
• We are not multi-tenant, so each customer has his own server instance.
• Updating the server at customer site happens at different times
• Client and server should update from single central repository
Managing the client
• At login time the client first queries the server for his OSGi version of the shared bundles
• Then he looks in the repo for updates that match the servers version in terms of „wire compatible“
Managing the client (2)
• If, at login time, server and client version do not match, Workbench starts up for getting the update with user interface disabled.
• If an update is available, but would need server upgrade first, it is ignored.
The solution: p2 queries
• We know the servers shared Bundle version, so we do a query for compatible updates of the product Installable Unit:
IQueryable<IInstallableUnit> queryable = provisioningContext.getMetadata(new NullProgressMonitor());
IQueryResult<IInstallableUnit> matches = queryable.query(QueryUtil.createIUQuery("de.eiswind.mango.client.core.mango", new VersionRange(Version.createOSGi(major, minor, micro), true,
Version.createOSGi(major, minor, micro + 1), false)),new NullProgressMonitor());
Building the Update
• The QueryResult gives us all compatible IU‘s from the repository. We pick the latest and construct an update:
IQueryResult<IInstallableUnit> allIUFromRepo = getAllInstallableUnitFromRepository(provisioningContext);
List<IInstallableUnit> units = new ArrayList<IInstallableUnit>();for (Iterator<IInstallableUnit> it = allIUFromRepo.iterator(); it.hasNext();) {
newIUFromRepo = it.next();units.add(newIUFromRepo);
}// check if something is available at all omitted hereCollections.sort(units);// get the latest matching updatenewIUFromRepo = units.get(units.size() - 1);
The UpdateOperation // now we must ensure that we don‘t get updates we// do not want
Update update = new Update(oldIUFromProfile, newIUFromRepo);
ProvisioningSession session = new ProvisioningSession(agent);final UpdateOperation operation = new UpdateOperation(session);status = operation.resolveModal(sub.newChild(100));// check status omitted here
operation.setSelectedUpdates(new Update[0]);for (Update available : operation.getPossibleUpdates()) {
if (available.equals(update)) {log(IStatus.INFO, "Update matches available: " + update, null); selected[0] = available;operation.setSelectedUpdates(selected);
}
// now run the ProvisioningJob
Coming up: The server
• Currently server is beeing ported to the virgoruntime
• Virgo doesn‘t work with p2 yet, but knows theconcept of a „remote repository“
Server updates
P2 and virgo repo on eiswind.de
Server at Customer BServer at Customer A
Pick up virgorepository updates
The update cycle
Server at Customer A
P2 and virgo repo on eiswind.de
1)
2) Client recognizes server update
3) Client pulls update from p2 repo
Thanks for listening
• If you‘d like to see the full update codeexample, just ask.
• You can reach me on
• http://www.eiswind.de
Top Related