Fix override of installed bundles
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 17 Dec 2023 11:31:20 +0000 (12:31 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 17 Dec 2023 11:31:20 +0000 (12:31 +0100)
org.argeo.init/src/org/argeo/init/a2/A2Component.java
org.argeo.init/src/org/argeo/init/a2/OsgiContext.java
org.argeo.init/src/org/argeo/init/a2/ProvisioningManager.java
org.argeo.init/src/org/argeo/init/osgi/OsgiBoot.java

index cc2f564716858b5dee3389404bf7fcf8a431dd1e..8942706300ee74b423c6e5cec959e68e600b9faa 100644 (file)
@@ -28,10 +28,11 @@ public class A2Component implements Comparable<A2Component> {
        }
 
        A2Branch getOrAddBranch(String branchId) {
-               if (branches.containsKey(branchId))
-                       return branches.get(branchId);
-               else
-                       return new A2Branch(this, branchId);
+               if (!branches.containsKey(branchId)) {
+                       A2Branch a2Branch = new A2Branch(this, branchId);
+                       branches.put(branchId, a2Branch);
+               }
+               return branches.get(branchId);
        }
 
        A2Module getOrAddModule(Version version, Object locator) {
index 0064ab9eddbb1c4d3c8c37148eb9efaaa68f61aa..7f1133f676a034a8b1fde29a4a683877dbe46b1b 100644 (file)
@@ -6,13 +6,18 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.Version;
 
-/** A running OSGi bundle context seen as a {@link AbstractProvisioningSource}. */
+/**
+ * A running OSGi bundle context seen as a {@link AbstractProvisioningSource}.
+ */
 class OsgiContext extends AbstractProvisioningSource {
        private final BundleContext bc;
 
+       private A2Contribution runtimeContribution;
+
        public OsgiContext(BundleContext bc) {
                super(false);
                this.bc = bc;
+               runtimeContribution = getOrAddContribution(A2Contribution.RUNTIME);
        }
 
        public OsgiContext() {
@@ -25,16 +30,19 @@ class OsgiContext extends AbstractProvisioningSource {
        }
 
        void load() {
-               A2Contribution runtimeContribution = getOrAddContribution( A2Contribution.RUNTIME);
                for (Bundle bundle : bc.getBundles()) {
-                       // OsgiBootUtils.debug(bundle.getDataFile("/"));
-                       String componentId = bundle.getSymbolicName();
-                       Version version = bundle.getVersion();
-                       A2Component component = runtimeContribution.getOrAddComponent(componentId);
-                       A2Module module = component.getOrAddModule(version, bundle);
-                       if (OsgiBootUtils.isDebug())
-                               OsgiBootUtils.debug("Registered " + module + " (location id: " + bundle.getLocation() + ")");
+                       registerBundle(bundle);
                }
 
        }
+
+       void registerBundle(Bundle bundle) {
+               String componentId = bundle.getSymbolicName();
+               Version version = bundle.getVersion();
+               A2Component component = runtimeContribution.getOrAddComponent(componentId);
+               A2Module module = component.getOrAddModule(version, bundle);
+               if (OsgiBootUtils.isDebug())
+                       OsgiBootUtils.debug("Registered bundle module " + module + " (location id: " + bundle.getLocation() + ")");
+
+       }
 }
index 6a0836bdfdea80ffc6727140e49d2dd3dcd3a470..92df47ea8f744e6d587a21c7baf91db2ea067377 100644 (file)
@@ -149,21 +149,28 @@ public class ProvisioningManager {
                        Version moduleVersion = module.getVersion();
                        A2Branch osgiBranch = osgiContext.findBranch(module.getBranch().getComponent().getId(), moduleVersion);
                        if (osgiBranch == null) {
-//                             Bundle bundle = bc.installBundle(module.getBranch().getCoordinates(),
-//                                             moduleSource.newInputStream(module.getLocator()));
                                Bundle bundle = moduleSource.install(bc, module);
-                               if (OsgiBootUtils.isDebug())
-                                       OsgiBootUtils.debug("Installed bundle " + bundle.getLocation() + " with version " + moduleVersion);
+                               // TODO make it more dynamic, based on OSGi APIs
+                               osgiContext.registerBundle(bundle);
+//                             if (OsgiBootUtils.isDebug())
+//                                     OsgiBootUtils.debug("Installed bundle " + bundle.getLocation() + " with version " + moduleVersion);
                                return bundle;
                        } else {
                                A2Module lastOsgiModule = osgiBranch.last();
                                int compare = moduleVersion.compareTo(lastOsgiModule.getVersion());
                                if (compare > 0) {// update
                                        Bundle bundle = (Bundle) lastOsgiModule.getLocator();
-//                                     bundle.update(moduleSource.newInputStream(module.getLocator()));
                                        moduleSource.update(bundle, module);
+                                       // TODO make it more dynamic, based on OSGi APIs
+                                       // TODO remove old module? Or keep update history?
+                                       osgiContext.registerBundle(bundle);
                                        OsgiBootUtils.info("Updated bundle " + bundle.getLocation() + " to version " + moduleVersion);
                                        return bundle;
+                               } else {
+                                       if (OsgiBootUtils.isDebug())
+                                               OsgiBootUtils.debug("Did not install as bundle module " + module
+                                                               + " since a module with higher version " + lastOsgiModule.getVersion()
+                                                               + " is already installed for branch " + osgiBranch);
                                }
                        }
                } catch (Exception e) {
index 2e96db3b37a769774f0c7b7d980ec1cb494549dd..f5b260caba404735f9f296830bab0e6e29c369bf 100644 (file)
@@ -381,7 +381,23 @@ public class OsgiBoot implements OsgiBootConstants {
                        for (String bsn : startLevels.get(level))
                                bundleStartLevels.put(bsn, level);
                }
-               for (Bundle bundle : bundleContext.getBundles()) {
+
+               // keep only bundles with the highest version
+               Map<String, Bundle> startableBundles = new HashMap<>();
+               bundles: for (Bundle bundle : bundleContext.getBundles()) {
+                       if (bundle.getVersion() == null)
+                               continue bundles;
+                       String bsn = bundle.getSymbolicName();
+                       if (!startableBundles.containsKey(bsn)) {
+                               startableBundles.put(bsn, bundle);
+                       } else {
+                               if (bundle.getVersion().compareTo(startableBundles.get(bsn).getVersion()) > 0) {
+                                       startableBundles.put(bsn, bundle);
+                               }
+                       }
+               }
+
+               for (Bundle bundle : startableBundles.values()) {
                        String bsn = bundle.getSymbolicName();
                        if (bundleStartLevels.containsKey(bsn)) {
                                BundleStartLevel bundleStartLevel = bundle.adapt(BundleStartLevel.class);
@@ -394,7 +410,7 @@ public class OsgiBoot implements OsgiBootConstants {
                                                OsgiBootUtils.error("Cannot mark " + bsn + " as started", e);
                                        }
                                        if (OsgiBootUtils.isDebug())
-                                               OsgiBootUtils.debug(bsn + " starts at level " + level);
+                                               OsgiBootUtils.debug(bsn + " v" + bundle.getVersion() + " starts at level " + level);
                                }
                        }
                }