0

In OSGi (Apache Felix 4.2.1), I want my bundles to check for updates automatically on startup.

I do this with the following code (in my "management agent"). How can I tell whether a bundle was updated?

Bundle[] bundles = context.getBundles();
for (int i = 0; i < bundles.length; i++) {
  Bundle bundle = bundles[i];
  bundle.update();
}
// which bundle was updated?

I want to refresh the bundles automatically (using FrameworkWiring), but only if one of the .update() calls actually resulted in a new deployment from my server.

As I'm deploying from Maven to my OBR, my SNAPSHOT version have all the same number. From gogo, I can see that the Bnd-LastModified header changes, but how to automate this?

PS: If easy solutions exist which solve the whole update thing more nicely than rolling my own, I'm interested as well. It needs to be lean. (Apache Karaf?, Apache ACE? others?)

Philipp
  • 4,659
  • 9
  • 48
  • 69

3 Answers3

3

They are all updated, because your code clearly calls update on all of them.

What you probably mean is how to tell whether a bundle needs to be updated. For this you could use the bundle.getLastModified() method, and compare it against the timestamp of the file. But this gets risky when you have timestamps generated by multiple computers, because their system clocks will never be precisely synchronized. If they are coming from a remote server (e.g. over HTTP) then forget it. You should probably use something like ETags or SHA hashing of the files after downloading.

Neil Bartlett
  • 23,743
  • 4
  • 44
  • 77
  • Can I compare the `getLastModified` of the current bundle, to the one on the server? Also to correct: the deployed SNAPSHOT has a timestamp in the jar name (so its name is unique and could identify whether an update is needed), but this is not reflected in the version in the `repository.xml`. – Philipp Apr 23 '14 at 13:20
  • What is the lastModified on the server? Do you mean there is another OSGi framework running on the server, or do you just mean the timestamp of the file? As I said, this is not very reliable because the two machines will have different system clocks. – Neil Bartlett Apr 23 '14 at 16:22
  • I thought maybe there was a way to read the header of the bundles from the server. I guess my best bet now is trying to include a timestamp in the version to make it unique. – Philipp Apr 23 '14 at 17:05
  • Or better, a content hash. If the hash of the bundle on the server is different from the one you have, then you know you need to download it. – Neil Bartlett Apr 24 '14 at 21:21
2

If you want to learn a bit more about Apache ACE, I can recommend reading the following two articles on the ACE website:

To be honest, if all you want is to updated a set of bundles on startup, then ACE is a bit overkill. It can be used to manage multiple "targets" (frameworks running OSGi) from a central server, automatically pushing updates to it and managing large sets of bundles and other artifacts, grouping them in features and distributions.

Marcel Offermans
  • 3,313
  • 1
  • 15
  • 23
  • 1
    I tested ACE and am impressed. It also fulfills other needs I have. Nonetheless I have many questions about it - I will ask those on the mailing list. – Philipp Apr 24 '14 at 06:28
  • @Philipp Could u remotely install a bundle in a target? I don't know how to add a target in the ACE. I mean how to bind a target with a running server. I couldn't find good explanations in the documentations also. I want to bind RPi with a server which is running in my PC and update/install bundles remotely. – hatef Apr 28 '14 at 14:07
  • 1
    For my tests I ran the target and server on the same machine. But in your case when starting the target client you can specify the server as a property. See the user guide on the ace web site. – Philipp Apr 28 '14 at 15:10
  • I ended up using ACE - very nice tool. – Philipp Nov 05 '14 at 15:49
0

Have you tried to implement a listener?

Stefan
  • 12,108
  • 5
  • 47
  • 66
  • It seems the listener is called in any case on update - independently if the bundle on the server is newer or not. – Philipp Apr 23 '14 at 12:25
  • Yes you need to ask the incoming [BundleEvent](http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleEvent.html) for its state: static int UPDATED - The bundle has been updated. – Stefan Apr 23 '14 at 12:27
  • Yes, I do that. `if(event.getType() == BundleEvent.UPDATED){` – Philipp Apr 23 '14 at 12:28