Repository: karaf Updated Branches: refs/heads/karaf-2.x 70774bc0b -> b2c7c3289
[KARAF-3642]bundles mistaken got unstalled even though it has a depending feature with it. Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b2c7c328 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b2c7c328 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b2c7c328 Branch: refs/heads/karaf-2.x Commit: b2c7c328991e562f76e87e23eea231c378886173 Parents: 70774bc Author: Freeman Fang <[email protected]> Authored: Wed Apr 1 18:41:08 2015 +0800 Committer: Freeman Fang <[email protected]> Committed: Wed Apr 1 18:41:08 2015 +0800 ---------------------------------------------------------------------- .../features/internal/FeaturesServiceImpl.java | 75 ++++++++++++++++++-- .../karaf/features/FeaturesServiceTest.java | 10 +-- .../internal/FeaturesServiceImplTest.java | 9 +++ 3 files changed, 82 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/b2c7c328/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java index b937851..45f3e4c 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java @@ -736,16 +736,77 @@ public class FeaturesServiceImpl implements FeaturesService { startBundleIfNeeded(result.getBundle(), result.getStartLevel()); } } + + for (BundleInfo bInfo : feature.getBundles()) { + Bundle bundle = isBundleInstalled(bInfo); + if (bundle != null && !bundles.contains(bundle.getBundleId())) { + bundles.add(bundle.getBundleId()); + } + } state.features.put(feature, bundles); } + + protected Bundle isBundleInstalled(BundleInfo bundleInfo) throws IOException, BundleException { + InputStream is; + String bundleLocation = bundleInfo.getLocation(); + LOGGER.debug("Checking " + bundleLocation); + try { + is = new BufferedInputStream(new URL(bundleLocation).openStream()); + } catch (RuntimeException e) { + LOGGER.error(e.getMessage()); + throw e; + } + try { + is.mark(256 * 1024); + JarInputStream jar = new JarInputStream(is); + Manifest m = jar.getManifest(); + if (m == null) { + ZipEntry entry; + while ((entry = jar.getNextEntry()) != null) { + if (MANIFEST_NAME.equals(entry.getName())) { + m = new Manifest(jar); + break; + } + } + if (m == null) { + throw new BundleException("Manifest not present in the zip " + bundleLocation); + } + } + String sn = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME); + if (sn == null) { + throw new BundleException("Jar is not a bundle, no Bundle-SymbolicName " + bundleLocation); + } + // remove attributes from the symbolic name (like ;blueprint.graceperiod:=false suffix) + int attributeIndexSep = sn.indexOf(';'); + if (attributeIndexSep != -1) { + sn = sn.substring(0, attributeIndexSep); + } + String vStr = m.getMainAttributes().getValue(Constants.BUNDLE_VERSION); + Version v = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr); + for (Bundle b : bundleContext.getBundles()) { + if (b.getSymbolicName() != null && b.getSymbolicName().equals(sn)) { + vStr = (String) b.getHeaders().get(Constants.BUNDLE_VERSION); + Version bv = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr); + if (v.equals(bv)) { + LOGGER.debug("Found installed bundle: " + b); + return b; + } + } + } + return null; + } finally { + is.close(); + } + + } - private Dictionary<String, String> convertToDict(Map<String, String> props) { - Dictionary<String, String> cfgProps = new Hashtable<String, String>(); - for (Entry<String, String> property : props.entrySet()) { - cfgProps.put(property.getKey(), property.getValue()); - } - return cfgProps; - } + private Dictionary<String, String> convertToDict(Map<String, String> props) { + Dictionary<String, String> cfgProps = new Hashtable<String, String>(); + for (Entry<String, String> property : props.entrySet()) { + cfgProps.put(property.getKey(), property.getValue()); + } + return cfgProps; + } private String createConfigurationKey(String pid, String factoryPid) { return factoryPid == null ? pid : pid + "-" + factoryPid; http://git-wip-us.apache.org/repos/asf/karaf/blob/b2c7c328/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java ---------------------------------------------------------------------- diff --git a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java index 46897bb..9ccc4db 100644 --- a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java +++ b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java @@ -122,7 +122,7 @@ public class FeaturesServiceTest extends TestCase { // required since the sorted set uses it expect(installedBundle.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes(); - expect(bundleContext.getBundles()).andReturn(new Bundle[0]); + expect(bundleContext.getBundles()).andReturn(new Bundle[0]).times(3); expect(bundleContext.installBundle(isA(String.class), isA(InputStream.class))).andReturn(installedBundle); expect(installedBundle.getBundleId()).andReturn(12345L); @@ -182,7 +182,7 @@ public class FeaturesServiceTest extends TestCase { expect(installedBundle.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes(); // Installs f1 and 0.1 - expect(bundleContext.getBundles()).andReturn(new Bundle[0]); + expect(bundleContext.getBundles()).andReturn(new Bundle[0]).times(3); expect(bundleContext.installBundle(isA(String.class), isA(InputStream.class))).andReturn(installedBundle); expect(installedBundle.getBundleId()).andReturn(12345L); @@ -788,7 +788,7 @@ public class FeaturesServiceTest extends TestCase { expect(installedBundle2.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes(); // Installs feature f1 and f2 - expect(bundleContext.getBundles()).andReturn(new Bundle[0]); + expect(bundleContext.getBundles()).andReturn(new Bundle[0]).times(3); expect(bundleContext.installBundle(eq(bundle1), isA(InputStream.class))).andReturn(installedBundle1); expect(installedBundle1.getBundleId()).andReturn(12345L); expect(installedBundle1.getBundleId()).andReturn(12345L); @@ -849,7 +849,7 @@ public class FeaturesServiceTest extends TestCase { expect(installedBundle2.compareTo(EasyMock.<Bundle>anyObject())).andReturn(0).anyTimes(); // Installs feature f1 and f2 - expect(bundleContext.getBundles()).andReturn(new Bundle[0]); + expect(bundleContext.getBundles()).andReturn(new Bundle[0]).times(3); expect(bundleContext.installBundle(eq(bundle1), isA(InputStream.class))).andReturn(installedBundle1); expect(installedBundle1.getBundleId()).andReturn(12345L); expect(installedBundle1.getBundleId()).andReturn(12345L); @@ -922,7 +922,7 @@ public class FeaturesServiceTest extends TestCase { expect(installedBundle1.getBundleId()).andReturn(12345L); expect(installedBundle1.getSymbolicName()).andReturn(headers.get(Constants.BUNDLE_SYMBOLICNAME)).anyTimes(); expect(installedBundle1.getHeaders()).andReturn(headers).anyTimes(); - expect(bundleContext.getBundles()).andReturn(new Bundle[] { installedBundle1 }); + expect(bundleContext.getBundles()).andReturn(new Bundle[] { installedBundle1 }).times(3); expect(bundleContext.getBundles()).andReturn(new Bundle[] { installedBundle1 }); expect(bundleContext.installBundle(eq(bundle2), isA(InputStream.class))).andReturn(installedBundle2); http://git-wip-us.apache.org/repos/asf/karaf/blob/b2c7c328/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java ---------------------------------------------------------------------- diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java index 51cec18..b6e5304 100644 --- a/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java +++ b/features/core/src/test/java/org/apache/karaf/features/internal/FeaturesServiceImplTest.java @@ -218,6 +218,15 @@ public class FeaturesServiceImplTest extends TestCase { replay(bundle); return new InstallResult(false, bundle, 0); } + + @Override + protected Bundle isBundleInstalled(BundleInfo bundleInfo) throws IOException, BundleException { + // let's return a mock bundle and bundle id to keep the features service happy + Bundle bundle = createNiceMock(Bundle.class); + expect(bundle.getBundleId()).andReturn(10l).anyTimes(); + replay(bundle); + return bundle; + } @Override protected Set<Bundle> findBundlesToRefresh() {
