You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by ff...@apache.org on 2015/04/01 12:41:24 UTC

karaf git commit: [KARAF-3642]bundles mistaken got unstalled even though it has a depending feature with it.

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 <fr...@gmail.com>
Authored: Wed Apr 1 18:41:08 2015 +0800
Committer: Freeman Fang <fr...@gmail.com>
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() {