summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorgjoranv <gv@verizonmedia.com>2020-07-16 10:11:49 +0200
committergjoranv <gv@verizonmedia.com>2020-07-16 10:12:19 +0200
commit1eb5aeac9e1ad94f4e5d290cd57264541968454b (patch)
tree0db6722d283c5f5080a8a9dc81c0d6bfa5fea6b9 /container-core
parentc608c8384315cebdc8adacb012a8c49a09cc0340 (diff)
Reapply "Load platform bundles separately"
This reverts commit 0355cb740fe498abc03861bcb64de5e418c2fa88.
Diffstat (limited to 'container-core')
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/ApplicationBundleLoader.java165
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/BundleManager.java236
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java18
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/PlatformBundleLoader.java45
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java3
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/testutil/MockOsgiWrapper.java5
-rw-r--r--container-core/src/main/java/com/yahoo/osgi/MockOsgi.java6
-rw-r--r--container-core/src/main/java/com/yahoo/osgi/Osgi.java6
-rw-r--r--container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java12
-rw-r--r--container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java (renamed from container-core/src/test/java/com/yahoo/container/core/config/BundleManagerTest.java)16
10 files changed, 246 insertions, 266 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/ApplicationBundleLoader.java b/container-core/src/main/java/com/yahoo/container/core/config/ApplicationBundleLoader.java
new file mode 100644
index 00000000000..e20fbd7b2ae
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/core/config/ApplicationBundleLoader.java
@@ -0,0 +1,165 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.core.config;
+
+import com.yahoo.config.FileReference;
+import com.yahoo.container.Container;
+import com.yahoo.filedistribution.fileacquirer.FileAcquirer;
+import com.yahoo.osgi.Osgi;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleRevision;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ * Manages the set of installed and active/inactive bundles.
+ *
+ * @author gjoranv
+ * @author Tony Vaagenes
+ */
+public class ApplicationBundleLoader {
+
+ /* Map of file refs of active bundles (not scheduled for uninstall) to the installed bundle.
+ *
+ * Used to:
+ * 1. Avoid installing already installed bundles. Just an optimization, installing the same bundle location is a NOP
+ * 2. Start bundles (all are started every time)
+ * 3. Calculate the set of bundles to uninstall
+ */
+ private final Map<FileReference, Bundle> reference2Bundle = new LinkedHashMap<>();
+
+ private final Logger log = Logger.getLogger(ApplicationBundleLoader.class.getName());
+ private final Osgi osgi;
+
+ // A custom bundle installer for non-disk bundles, to be used for testing
+ private BundleInstaller customBundleInstaller = null;
+
+ public ApplicationBundleLoader(Osgi osgi) {
+ this.osgi = osgi;
+ }
+
+ /**
+ * Installs the given set of bundles and returns the set of bundles that is no longer used
+ * by the application, and should therefore be scheduled for uninstall.
+ */
+ public synchronized Set<Bundle> useBundles(List<FileReference> newFileReferences) {
+
+ Set<FileReference> obsoleteReferences = getObsoleteFileReferences(newFileReferences);
+ Set<Bundle> bundlesToUninstall = getObsoleteBundles(obsoleteReferences);
+ log.info("Bundles to schedule for uninstall: " + bundlesToUninstall);
+
+ osgi.allowDuplicateBundles(bundlesToUninstall);
+ removeInactiveFileReferences(obsoleteReferences);
+
+ installBundles(newFileReferences);
+ startBundles();
+ log.info(installedBundlesMessage());
+
+ return bundlesToUninstall;
+ }
+
+ private Set<FileReference> getObsoleteFileReferences(List<FileReference> newReferences) {
+ Set<FileReference> obsoleteReferences = new HashSet<>(reference2Bundle.keySet());
+ obsoleteReferences.removeAll(newReferences);
+ return obsoleteReferences;
+ }
+
+
+ /**
+ * Returns the bundles that will not be retained by the new application generation.
+ */
+ private Set<Bundle> getObsoleteBundles(Set<FileReference> obsoleteReferences) {
+ return obsoleteReferences.stream().map(reference2Bundle::get).collect(Collectors.toSet());
+ }
+
+ private void removeInactiveFileReferences(Set<FileReference> fileReferencesToRemove) {
+ fileReferencesToRemove.forEach(reference2Bundle::remove);
+ }
+
+ private void installBundles(List<FileReference> references) {
+ Set<FileReference> bundlesToInstall = new HashSet<>(references);
+
+ // This is just an optimization, as installing a bundle with the same location id returns the already installed bundle.
+ bundlesToInstall.removeAll(reference2Bundle.keySet());
+
+ if (!bundlesToInstall.isEmpty()) {
+ FileAcquirer fileAcquirer = Container.get().getFileAcquirer();
+ boolean hasFileDistribution = (fileAcquirer != null);
+ if (hasFileDistribution) {
+ installWithFileDistribution(bundlesToInstall, new FileAcquirerBundleInstaller(fileAcquirer));
+ } else if (customBundleInstaller != null) {
+ installWithFileDistribution(bundlesToInstall, customBundleInstaller);
+ } else {
+ log.warning("Can't retrieve bundles since file distribution is disabled.");
+ }
+ }
+ }
+
+ private void installWithFileDistribution(Set<FileReference> bundlesToInstall, BundleInstaller bundleInstaller) {
+ for (FileReference reference : bundlesToInstall) {
+ try {
+ log.info("Installing bundle with reference '" + reference.value() + "'");
+ List<Bundle> bundles = bundleInstaller.installBundles(reference, osgi);
+
+ // Throw if more than one bundle was installed, which means that the X-JDisc-Preinstall-Bundle header was used.
+ // However, if the OSGi framework is only a test framework, this rule does not apply.
+ if (bundles.size() > 1 && osgi.hasFelixFramework()) {
+ throw new RuntimeException("Bundle '" + bundles.get(0).getSymbolicName() + "' tried to pre-install other bundles.");
+ }
+ reference2Bundle.put(reference, bundles.get(0));
+ }
+ catch(Exception e) {
+ throw new RuntimeException("Could not install bundle with reference '" + reference + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Resolves and starts (calls the Bundles BundleActivator) all bundles. Bundle resolution must take place
+ * after all bundles are installed to ensure that the framework can resolve dependencies between bundles.
+ */
+ private void startBundles() {
+ for (var bundle : reference2Bundle.values()) {
+ try {
+ if ( ! isFragment(bundle))
+ bundle.start(); // NOP for already ACTIVE bundles
+ } catch(Exception e) {
+ throw new RuntimeException("Could not start bundle '" + bundle.getSymbolicName() + "'", e);
+ }
+ }
+ }
+
+ private boolean isFragment(Bundle bundle) {
+ BundleRevision bundleRevision = bundle.adapt(BundleRevision.class);
+ if (bundleRevision == null)
+ throw new NullPointerException("Null bundle revision means that bundle has probably been uninstalled: " +
+ bundle.getSymbolicName() + ":" + bundle.getVersion());
+ return (bundleRevision.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
+ }
+
+ private String installedBundlesMessage() {
+ StringBuilder sb = new StringBuilder("Installed bundles: {" );
+ for (Bundle b : osgi.getBundles())
+ sb.append("[" + b.getBundleId() + "]" + b.getSymbolicName() + ":" + b.getVersion() + ", ");
+ sb.setLength(sb.length() - 2);
+ sb.append("}");
+ return sb.toString();
+ }
+
+ // Only for testing
+ void useCustomBundleInstaller(BundleInstaller bundleInstaller) {
+ customBundleInstaller = bundleInstaller;
+ }
+
+ // Only for testing
+ List<FileReference> getActiveFileReferences() {
+ return new ArrayList<>(reference2Bundle.keySet());
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/BundleManager.java b/container-core/src/main/java/com/yahoo/container/core/config/BundleManager.java
deleted file mode 100644
index 406d68408e3..00000000000
--- a/container-core/src/main/java/com/yahoo/container/core/config/BundleManager.java
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.container.core.config;
-
-import com.yahoo.collections.PredicateSplit;
-import com.yahoo.config.FileReference;
-import com.yahoo.container.Container;
-import com.yahoo.filedistribution.fileacquirer.FileAcquirer;
-import com.yahoo.osgi.Osgi;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleRevision;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-
-import static com.yahoo.collections.PredicateSplit.partition;
-import static com.yahoo.container.core.BundleLoaderProperties.DISK_BUNDLE_PREFIX;
-
-/**
- * Manages the set of installed and active/inactive bundles.
- *
- * @author gjoranv
- * @author Tony Vaagenes
- */
-public class BundleManager {
-
- /* Map of file refs of active bundles (not scheduled for uninstall) to a list of all bundles that were installed
- * (pre-install directive) by the bundle pointed to by the file ref (including itself).
- *
- * Used to:
- * 1. Avoid installing already installed bundles. Just an optimization, installing the same bundle location is a NOP
- * 2. Start bundles (all are started every time)
- * 3. Calculate the set of bundles to uninstall
- */
- private final Map<FileReference, List<Bundle>> reference2Bundles = new LinkedHashMap<>();
-
- private final Logger log = Logger.getLogger(BundleManager.class.getName());
- private final Osgi osgi;
-
- // A custom bundle installer for non-disk bundles, to be used for testing
- private BundleInstaller customBundleInstaller = null;
-
- public BundleManager(Osgi osgi) {
- this.osgi = osgi;
- }
-
- /**
- * Installs the given set of bundles and returns the set of bundles that is no longer used
- * by the application, and should therefore be scheduled for uninstall.
- */
- public synchronized Set<Bundle> use(List<FileReference> newFileReferences) {
- // Must be done before allowing duplicates because allowed duplicates affect osgi.getCurrentBundles
- Set<Bundle> bundlesToUninstall = getObsoleteBundles(newFileReferences);
-
- Set<FileReference> obsoleteReferences = getObsoleteFileReferences(newFileReferences);
- allowDuplicateBundles(obsoleteReferences);
- removeInactiveFileReferences(obsoleteReferences);
-
- installBundles(newFileReferences);
- startBundles();
-
- bundlesToUninstall.removeAll(allActiveBundles());
- log.info("Bundles to schedule for uninstall: " + bundlesToUninstall);
-
- log.info(installedBundlesMessage());
- return bundlesToUninstall;
- }
-
- /**
- * Returns the bundles that are not assumed to be retained by the new application generation.
- * Note that at this point we don't yet know the full set of new bundles, because of the potential
- * pre-install directives in the new bundles. However, only "disk bundles" (file:) can be listed
- * in the pre-install directive, so we know about all the obsolete application bundles.
- */
- private Set<Bundle> getObsoleteBundles(List<FileReference> newReferences) {
- Set<Bundle> bundlesToRemove = new HashSet<>(osgi.getCurrentBundles());
-
- for (FileReference fileReferenceToKeep : newReferences) {
- if (reference2Bundles.containsKey(fileReferenceToKeep)) {
- bundlesToRemove.removeAll(reference2Bundles.get(fileReferenceToKeep));
- }
- }
- bundlesToRemove.removeAll(osgi.getInitialBundles());
- return bundlesToRemove;
- }
-
-
- private Set<FileReference> getObsoleteFileReferences(List<FileReference> newReferences) {
- Set<FileReference> obsoleteReferences = new HashSet<>(reference2Bundles.keySet());
- obsoleteReferences.removeAll(newReferences);
- return obsoleteReferences;
- }
-
- /**
- * Allow duplicates (bsn+version) for each bundle that corresponds to obsolete file references,
- * and avoid allowing duplicates for bundles that were installed via the
- * X-JDisc-Preinstall-Bundle directive. These bundles are always "disk bundles" (library
- * bundles installed on the node, and not transferred via file distribution).
- * Such bundles will never have duplicates because they always have the same location id.
- */
- private void allowDuplicateBundles(Set<FileReference> obsoleteReferences) {
- // The bundle at index 0 for each file reference always corresponds to the bundle at the file reference location
- Set<Bundle> allowedDuplicates = obsoleteReferences.stream()
- .filter(reference -> ! isDiskBundle(reference))
- .map(reference -> reference2Bundles.get(reference).get(0))
- .collect(Collectors.toSet());
-
- log.info(() -> allowedDuplicates.isEmpty() ? "" : "Adding bundles to allowed duplicates: " + allowedDuplicates);
- osgi.allowDuplicateBundles(allowedDuplicates);
- }
-
- /**
- * Cleans up the map of active file references
- */
- private void removeInactiveFileReferences(Set<FileReference> fileReferencesToRemove) {
- // Clean up the map of active bundles
- fileReferencesToRemove.forEach(reference2Bundles::remove);
- }
-
- private void installBundles(List<FileReference> references) {
- Set<FileReference> bundlesToInstall = new HashSet<>(references);
-
- // This is just an optimization, as installing a bundle with the same location id returns the already installed bundle.
- bundlesToInstall.removeAll(reference2Bundles.keySet());
-
- PredicateSplit<FileReference> bundlesToInstall_isDisk = partition(bundlesToInstall, BundleManager::isDiskBundle);
- installBundlesFromDisk(bundlesToInstall_isDisk.trueValues);
- installBundlesFromFileDistribution(bundlesToInstall_isDisk.falseValues);
- }
-
- private static boolean isDiskBundle(FileReference fileReference) {
- return fileReference.value().startsWith(DISK_BUNDLE_PREFIX);
- }
-
- private void installBundlesFromDisk(List<FileReference> bundlesToInstall) {
- for (FileReference reference : bundlesToInstall) {
- try {
- installBundleFromDisk(reference);
- }
- catch(Exception e) {
- throw new RuntimeException("Could not install bundle '" + reference + "'", e);
- }
- }
- }
-
- private void installBundlesFromFileDistribution(List<FileReference> bundlesToInstall) {
- if (!bundlesToInstall.isEmpty()) {
- FileAcquirer fileAcquirer = Container.get().getFileAcquirer();
- boolean hasFileDistribution = (fileAcquirer != null);
- if (hasFileDistribution) {
- installWithFileDistribution(bundlesToInstall, new FileAcquirerBundleInstaller(fileAcquirer));
- } else if (customBundleInstaller != null) {
- installWithFileDistribution(bundlesToInstall, customBundleInstaller);
- } else {
- log.warning("Can't retrieve bundles since file distribution is disabled.");
- }
- }
- }
-
- private void installBundleFromDisk(FileReference reference) {
- log.info("Installing bundle from disk with reference '" + reference.value() + "'");
-
- var bundleInstaller = new DiskBundleInstaller();
- List<Bundle> bundles = bundleInstaller.installBundles(reference, osgi);
- reference2Bundles.put(reference, bundles);
- }
-
- private void installWithFileDistribution(List<FileReference> bundlesToInstall, BundleInstaller bundleInstaller) {
- for (FileReference reference : bundlesToInstall) {
- try {
- log.info("Installing bundle with reference '" + reference.value() + "'");
- List<Bundle> bundles = bundleInstaller.installBundles(reference, osgi);
- reference2Bundles.put(reference, bundles);
- }
- catch(Exception e) {
- throw new RuntimeException("Could not install bundle '" + reference + "'", e);
- }
- }
- }
-
- /**
- * Resolves and starts (calls the Bundles BundleActivator) all bundles. Bundle resolution must take place
- * after all bundles are installed to ensure that the framework can resolve dependencies between bundles.
- */
- private void startBundles() {
- for (List<Bundle> bundles : reference2Bundles.values()) {
- for (Bundle bundle : bundles) {
- try {
- if ( ! isFragment(bundle))
- bundle.start(); // NOP for already ACTIVE bundles
- } catch(Exception e) {
- throw new RuntimeException("Could not start bundle '" + bundle.getSymbolicName() + "'", e);
- }
- }
- }
- }
-
- private boolean isFragment(Bundle bundle) {
- BundleRevision bundleRevision = bundle.adapt(BundleRevision.class);
- if (bundleRevision == null)
- throw new NullPointerException("Null bundle revision means that bundle has probably been uninstalled: " +
- bundle.getSymbolicName() + ":" + bundle.getVersion());
- return (bundleRevision.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
- }
-
- private Set<Bundle> allActiveBundles() {
- return reference2Bundles.keySet().stream()
- .flatMap(reference -> reference2Bundles.get(reference).stream())
- .collect(Collectors.toSet());
- }
-
- private String installedBundlesMessage() {
- StringBuilder sb = new StringBuilder("Installed bundles: {" );
- for (Bundle b : osgi.getBundles())
- sb.append("[" + b.getBundleId() + "]" + b.getSymbolicName() + ":" + b.getVersion() + ", ");
- sb.setLength(sb.length() - 2);
- sb.append("}");
- return sb.toString();
- }
-
- // Only for testing
- void useCustomBundleInstaller(BundleInstaller bundleInstaller) {
- customBundleInstaller = bundleInstaller;
- }
-
- // Only for testing
- List<FileReference> getActiveFileReferences() {
- return new ArrayList<>(reference2Bundles.keySet());
- }
-
-}
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java b/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
index b983cbcfe37..40470a9f096 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
@@ -101,12 +101,16 @@ public class HandlersConfigurerDi {
private static class ContainerAndDiOsgi extends OsgiImpl implements OsgiWrapper {
private final OsgiFramework osgiFramework;
- private final BundleManager bundleManager;
+ private final ApplicationBundleLoader applicationBundleLoader;
+ private final PlatformBundleLoader platformBundleLoader;
public ContainerAndDiOsgi(OsgiFramework osgiFramework) {
super(osgiFramework);
this.osgiFramework = osgiFramework;
- bundleManager = new BundleManager(new OsgiImpl(osgiFramework));
+
+ OsgiImpl osgi = new OsgiImpl(osgiFramework);
+ applicationBundleLoader = new ApplicationBundleLoader(osgi);
+ platformBundleLoader = new PlatformBundleLoader(osgi);
}
@@ -131,9 +135,15 @@ public class HandlersConfigurerDi {
}
@Override
- public Set<Bundle> useBundles(Collection<FileReference> bundles) {
+ public void installPlatformBundles(Collection<FileReference> bundles) {
+ log.fine("Installing platform bundles.");
+ platformBundleLoader.install(bundles);
+ }
+
+ @Override
+ public Set<Bundle> useApplicationBundles(Collection<FileReference> bundles) {
log.info("Installing bundles from the latest application");
- return bundleManager.use(new ArrayList<>(bundles));
+ return applicationBundleLoader.useBundles(new ArrayList<>(bundles));
}
}
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/PlatformBundleLoader.java b/container-core/src/main/java/com/yahoo/container/core/config/PlatformBundleLoader.java
new file mode 100644
index 00000000000..76f0b959a58
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/core/config/PlatformBundleLoader.java
@@ -0,0 +1,45 @@
+package com.yahoo.container.core.config;
+
+import com.yahoo.config.FileReference;
+import com.yahoo.osgi.Osgi;
+import org.osgi.framework.Bundle;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Installs all platform bundles, using the {@link DiskBundleInstaller}.
+ * All platform bundles reside on disk, and they are never uninstalled.
+ *
+ * @author gjoranv
+ */
+public class PlatformBundleLoader {
+ private static final Logger log = Logger.getLogger(PlatformBundleLoader.class.getName());
+
+ private final Osgi osgi;
+ private final DiskBundleInstaller installer;
+
+ public PlatformBundleLoader(Osgi osgi) {
+ this.osgi = osgi;
+ installer = new DiskBundleInstaller();
+ }
+
+ public void install(Collection<FileReference> bundlesToInstall) {
+ for (FileReference reference : bundlesToInstall) {
+ try {
+ installBundleFromDisk(reference);
+ }
+ catch(Exception e) {
+ throw new RuntimeException("Could not install bundle '" + reference + "'", e);
+ }
+ }
+ }
+
+ private void installBundleFromDisk(FileReference reference) {
+ log.info("Installing bundle from disk with reference '" + reference.value() + "'");
+ List<Bundle> bundles = installer.installBundles(reference, osgi);
+ log.fine("Installed " + bundles.size() + " bundles for file reference " + reference);
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
index 9f49b016b68..503bf2f2db1 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
@@ -41,7 +41,8 @@ public class HandlersConfigurerTestWrapper {
private final static String testFiles[] = {
"components.cfg",
"handlers.cfg",
- "bundles.cfg",
+ "platform-bundles.cfg",
+ "application-bundles.cfg",
"string.cfg",
"int.cfg",
"renderers.cfg",
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/testutil/MockOsgiWrapper.java b/container-core/src/main/java/com/yahoo/container/core/config/testutil/MockOsgiWrapper.java
index ac0fbd71671..98c927b8efd 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/testutil/MockOsgiWrapper.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/testutil/MockOsgiWrapper.java
@@ -16,11 +16,6 @@ import static java.util.Collections.emptyList;
public class MockOsgiWrapper implements OsgiWrapper {
@Override
- public List<Bundle> getInitialBundles() {
- return emptyList();
- }
-
- @Override
public Bundle[] getBundles() {
return new Bundle[0];
}
diff --git a/container-core/src/main/java/com/yahoo/osgi/MockOsgi.java b/container-core/src/main/java/com/yahoo/osgi/MockOsgi.java
index d809c493565..6a700a65a03 100644
--- a/container-core/src/main/java/com/yahoo/osgi/MockOsgi.java
+++ b/container-core/src/main/java/com/yahoo/osgi/MockOsgi.java
@@ -12,15 +12,11 @@ import java.util.List;
/**
* @author Tony Vaagenes
+ * @author gjoranv
*/
public class MockOsgi extends NonWorkingOsgiFramework implements Osgi {
@Override
- public List<Bundle> getInitialBundles() {
- return Collections.emptyList();
- }
-
- @Override
public Bundle[] getBundles() {
return new Bundle[0];
}
diff --git a/container-core/src/main/java/com/yahoo/osgi/Osgi.java b/container-core/src/main/java/com/yahoo/osgi/Osgi.java
index 8f0acf41f30..513e7883594 100644
--- a/container-core/src/main/java/com/yahoo/osgi/Osgi.java
+++ b/container-core/src/main/java/com/yahoo/osgi/Osgi.java
@@ -9,11 +9,10 @@ import java.util.List;
/**
* @author Tony Vaagenes
+ * @author gjoranv
*/
public interface Osgi {
- List<Bundle> getInitialBundles();
-
Bundle[] getBundles();
/** Returns all bundles that have not been scheduled for uninstall. */
@@ -25,4 +24,7 @@ public interface Osgi {
void allowDuplicateBundles(Collection<Bundle> bundles);
+ default boolean hasFelixFramework() {
+ return false;
+ }
}
diff --git a/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java b/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
index ed93d15c975..998273acfc7 100644
--- a/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
+++ b/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
@@ -5,6 +5,7 @@ import com.yahoo.component.ComponentSpecification;
import com.yahoo.component.Version;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.jdisc.application.OsgiFramework;
+import com.yahoo.jdisc.core.FelixFramework;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.launch.Framework;
@@ -16,6 +17,7 @@ import java.util.logging.Logger;
/**
* @author Tony Vaagenes
* @author bratseth
+ * @author gjoranv
*/
public class OsgiImpl implements Osgi {
private static final Logger log = Logger.getLogger(OsgiImpl.class.getName());
@@ -42,11 +44,6 @@ public class OsgiImpl implements Osgi {
}
@Override
- public List<Bundle> getInitialBundles() {
- return initialBundles;
- }
-
- @Override
public Bundle[] getBundles() {
List<Bundle> bundles = jdiscOsgi.bundles();
return bundles.toArray(new Bundle[bundles.size()]);
@@ -155,6 +152,11 @@ public class OsgiImpl implements Osgi {
jdiscOsgi.allowDuplicateBundles(bundles);
}
+ @Override
+ public boolean hasFelixFramework() {
+ return jdiscOsgi instanceof FelixFramework;
+ }
+
private static Bundle firstNonFrameworkBundle(List<Bundle> bundles) {
for (Bundle b : bundles) {
if (! (b instanceof Framework))
diff --git a/container-core/src/test/java/com/yahoo/container/core/config/BundleManagerTest.java b/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java
index 414e6b05128..ee71e8a8f4c 100644
--- a/container-core/src/test/java/com/yahoo/container/core/config/BundleManagerTest.java
+++ b/container-core/src/test/java/com/yahoo/container/core/config/ApplicationBundleLoaderTest.java
@@ -16,27 +16,27 @@ import static org.junit.Assert.assertTrue;
/**
* @author gjoranv
*/
-public class BundleManagerTest {
+public class ApplicationBundleLoaderTest {
private static final FileReference BUNDLE_1_REF = new FileReference("bundle-1");
private static final Bundle BUNDLE_1 = new TestBundle(BUNDLE_1_REF.value());
private static final FileReference BUNDLE_2_REF = new FileReference("bundle-2");
private static final Bundle BUNDLE_2 = new TestBundle(BUNDLE_2_REF.value());
- private BundleManager bundleLoader;
+ private ApplicationBundleLoader bundleLoader;
private TestOsgi osgi;
@Before
public void setup() {
osgi = new TestOsgi(testBundles());
var bundleInstaller = new TestBundleInstaller();
- bundleLoader = new BundleManager(osgi);
+ bundleLoader = new ApplicationBundleLoader(osgi);
bundleLoader.useCustomBundleInstaller(bundleInstaller);
}
@Test
public void bundles_are_installed_and_started() {
- bundleLoader.use(List.of(BUNDLE_1_REF));
+ bundleLoader.useBundles(List.of(BUNDLE_1_REF));
assertEquals(1, osgi.getInstalledBundles().size());
// The bundle is installed and started
@@ -51,8 +51,8 @@ public class BundleManagerTest {
@Test
public void new_bundle_can_be_installed_in_reconfig() {
- bundleLoader.use(List.of(BUNDLE_1_REF));
- Set<Bundle> obsoleteBundles = bundleLoader.use(List.of(BUNDLE_1_REF, BUNDLE_2_REF));
+ bundleLoader.useBundles(List.of(BUNDLE_1_REF));
+ Set<Bundle> obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_1_REF, BUNDLE_2_REF));
// No bundles are obsolete
assertTrue(obsoleteBundles.isEmpty());
@@ -76,8 +76,8 @@ public class BundleManagerTest {
@Test
public void unused_bundle_is_marked_obsolete_after_reconfig() {
- bundleLoader.use(List.of(BUNDLE_1_REF));
- Set<Bundle> obsoleteBundles = bundleLoader.use(List.of(BUNDLE_2_REF));
+ bundleLoader.useBundles(List.of(BUNDLE_1_REF));
+ Set<Bundle> obsoleteBundles = bundleLoader.useBundles(List.of(BUNDLE_2_REF));
// The returned set of obsolete bundles contains bundle-1
assertEquals(1, obsoleteBundles.size());