You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/02/13 17:47:49 UTC

[2/2] karaf git commit: [KARAF-3528] When updating bundles, use the Bundle-UpdateLocation header

[KARAF-3528] When updating bundles, use the Bundle-UpdateLocation header

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/6d298958
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/6d298958
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/6d298958

Branch: refs/heads/master
Commit: 6d298958040e2d49d871e3bb11cb7ce58fcc68a8
Parents: 6f88c4e
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Fri Feb 13 17:18:53 2015 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Fri Feb 13 17:44:53 2015 +0100

----------------------------------------------------------------------
 bundle/core/pom.xml                             |  1 +
 .../org/apache/karaf/bundle/command/Update.java | 30 +++++++--
 .../bundle/core/internal/BundleWatcherImpl.java | 22 ++++++-
 features/core/pom.xml                           |  1 +
 .../features/internal/service/Deployer.java     |  6 +-
 .../internal/service/FeaturesServiceImpl.java   | 12 +++-
 .../features/internal/service/DeployerTest.java |  2 +-
 .../features/VerifyFeatureResolutionMojo.java   |  2 +-
 .../apache/karaf/util/bundles/BundleUtils.java  | 65 ++++++++++++++++++++
 9 files changed, 125 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/bundle/core/pom.xml
----------------------------------------------------------------------
diff --git a/bundle/core/pom.xml b/bundle/core/pom.xml
index dea1229..4a41e0d 100644
--- a/bundle/core/pom.xml
+++ b/bundle/core/pom.xml
@@ -131,6 +131,7 @@
                             org.apache.karaf.bundle.core.internal,
                             org.apache.karaf.bundle.core.internal.osgi,
                             org.apache.karaf.util,
+                            org.apache.karaf.util.bundles,
                             org.apache.karaf.util.jaas,
                             org.apache.karaf.util.maven,
                             org.apache.karaf.util.tracker,

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
index 5222822..4470f9f 100644
--- a/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/command/Update.java
@@ -16,13 +16,20 @@
  */
 package org.apache.karaf.bundle.command;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.net.URL;
 
 import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.util.bundles.BundleUtils;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 
 @Command(scope = "bundle", name = "update", description = "Update bundle.")
 @Service
@@ -33,15 +40,26 @@ public class Update extends BundleCommand {
 
     protected Object doExecute(Bundle bundle) throws Exception {
         if (location != null) {
-            try (
-                InputStream is = location.toURL().openStream()
-            ) {
-                bundle.update(is);
-            }
+            update(bundle, location.toURL());
         } else {
-            bundle.update();
+            String loc = bundle.getHeaders().get(Constants.BUNDLE_UPDATELOCATION);
+            if (loc != null && !loc.equals(bundle.getLocation())) {
+                update(bundle, new URL(loc));
+            } else {
+                bundle.update();
+            }
         }
         return null;
     }
 
+    private void update(Bundle bundle, URL location) throws IOException, BundleException {
+        try (InputStream is = location.openStream()) {
+            File file = BundleUtils.fixBundleWithUpdateLocation(is, location.toString());
+            try (FileInputStream fis = new FileInputStream(file)) {
+                bundle.update(fis);
+            }
+            file.delete();
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java
----------------------------------------------------------------------
diff --git a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java
index bd740cc..e92c95f 100644
--- a/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java
+++ b/bundle/core/src/main/java/org/apache/karaf/bundle/core/internal/BundleWatcherImpl.java
@@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.karaf.bundle.core.BundleInfo;
 import org.apache.karaf.bundle.core.BundleService;
 import org.apache.karaf.bundle.core.BundleWatcher;
+import org.apache.karaf.util.bundles.BundleUtils;
 import org.apache.karaf.util.maven.Parser;
 import org.osgi.framework.*;
 import org.osgi.framework.wiring.FrameworkWiring;
@@ -90,7 +91,7 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche
                     // Transform into regexp
                     bundleURL = bundleURL.replaceAll("\\*", ".*");
                     for (Bundle bundle : bundleService.selectBundles(Collections.singletonList(bundleURL), false)) {
-                        if (isMavenSnapshotUrl(bundle.getLocation())) {
+                        if (isMavenSnapshotUrl(getLocation(bundle))) {
                             watchedBundles.add(bundle);
                         }
                     }
@@ -147,6 +148,11 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche
         }
     }
 
+    private String getLocation(Bundle bundle) {
+        String location = bundle.getHeaders().get(Constants.BUNDLE_UPDATELOCATION);
+        return location != null ? location : bundle.getLocation();
+    }
+
     private boolean isMavenSnapshotUrl(String url) {
         return url.startsWith("mvn:") && url.contains("SNAPSHOT");
     }
@@ -163,7 +169,17 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche
                 } else {
                     bundle.stop(Bundle.STOP_TRANSIENT);
                 }
-                bundle.update(is);
+                // We don't really want to loose the update-location
+                String updateLocation = getLocation(bundle);
+                if (!updateLocation.equals(bundle.getLocation())) {
+                    File file = BundleUtils.fixBundleWithUpdateLocation(is, updateLocation);
+                    try (FileInputStream fis = new FileInputStream(file)) {
+                        bundle.update(fis);
+                    }
+                    file.delete();
+                } else {
+                    bundle.update(is);
+                }
                 updated.add(bundle);
             } finally {
                 is.close();
@@ -204,7 +220,7 @@ public class BundleWatcherImpl implements Runnable, BundleListener, BundleWatche
      */
     private File getBundleExternalLocation(File localRepository, Bundle bundle) {
         try {
-            Parser p = new Parser(bundle.getLocation().substring(4));
+            Parser p = new Parser(getLocation(bundle).substring(4));
             return new File(localRepository.getPath() + File.separator + p.getArtifactPath());
         } catch (MalformedURLException e) {
             logger.error("Could not parse artifact path for bundle" + bundle.getSymbolicName(), e);

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/features/core/pom.xml
----------------------------------------------------------------------
diff --git a/features/core/pom.xml b/features/core/pom.xml
index fc6ccc9..228107a 100644
--- a/features/core/pom.xml
+++ b/features/core/pom.xml
@@ -147,6 +147,7 @@
                             org.apache.felix.utils.properties,
                             org.apache.felix.utils.manifest,
                             org.apache.karaf.util,
+                            org.apache.karaf.util.bundles,
                             org.apache.karaf.util.collections,
                             org.apache.karaf.util.tracker,
                             org.eclipse.equinox.internal.region.*;-split-package:=merge-first,

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
index af6bfcc..61dd5c7 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
@@ -108,7 +108,7 @@ public class Deployer {
         void callListeners(FeatureEvent featureEvent);
 
         Bundle installBundle(String region, String uri, InputStream is) throws BundleException;
-        void updateBundle(Bundle bundle, InputStream is) throws BundleException;
+        void updateBundle(Bundle bundle, String uri, InputStream is) throws BundleException;
         void uninstall(Bundle bundle) throws BundleException;
         void startBundle(Bundle bundle) throws BundleException;
         void stopBundle(Bundle bundle, int options) throws BundleException;
@@ -507,7 +507,7 @@ public class Deployer {
             try (
                     InputStream is = getBundleInputStream(resource, providers)
             ) {
-                callback.updateBundle(dstate.serviceBundle, is);
+                callback.updateBundle(dstate.serviceBundle, uri, is);
             }
             callback.refreshPackages(toRefresh.keySet());
             callback.startBundle(dstate.serviceBundle);
@@ -624,7 +624,7 @@ public class Deployer {
                     try (
                             InputStream is = getBundleInputStream(resource, providers)
                     ) {
-                        callback.updateBundle(bundle, is);
+                        callback.updateBundle(bundle, uri, is);
                     }
                     toStart.add(bundle);
                 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index 477ef89..608bf78 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -59,6 +59,7 @@ import org.apache.karaf.features.internal.download.DownloadManager;
 import org.apache.karaf.features.internal.download.DownloadManagers;
 import org.apache.karaf.features.internal.util.JsonReader;
 import org.apache.karaf.features.internal.util.JsonWriter;
+import org.apache.karaf.util.bundles.BundleUtils;
 import org.apache.karaf.util.collections.CopyOnWriteArrayIdentityList;
 import org.eclipse.equinox.region.Region;
 import org.eclipse.equinox.region.RegionDigraph;
@@ -1117,8 +1118,15 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
     }
 
     @Override
-    public void updateBundle(Bundle bundle, InputStream is) throws BundleException {
-        bundle.update(is);
+    public void updateBundle(Bundle bundle, String uri, InputStream is) throws BundleException {
+        // We need to wrap the bundle to insert a Bundle-UpdateLocation header
+        try {
+            File file = BundleUtils.fixBundleWithUpdateLocation(is, uri);
+            bundle.update(new FileInputStream(file));
+            file.delete();
+        } catch (IOException e) {
+            throw new BundleException("Unable to update bundle", e);
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
index f5e05d1..3a43bda 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
@@ -137,7 +137,7 @@ public class DeployerTest {
                 return null;
             }
         });
-        callback.updateBundle(EasyMock.eq(bundleA), EasyMock.<InputStream>anyObject());
+        callback.updateBundle(EasyMock.eq(bundleA), EasyMock.<String>anyObject(), EasyMock.<InputStream>anyObject());
         EasyMock.expectLastCall().andStubAnswer(new IAnswer<Object>() {
             @Override
             public Object answer() throws Throwable {

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/VerifyFeatureResolutionMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/VerifyFeatureResolutionMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/VerifyFeatureResolutionMojo.java
index 0692b53..a68c6b0 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/VerifyFeatureResolutionMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/VerifyFeatureResolutionMojo.java
@@ -716,7 +716,7 @@ public class VerifyFeatureResolutionMojo extends MojoSupport {
         }
 
         @Override
-        public void updateBundle(Bundle bundle, InputStream is) throws BundleException {
+        public void updateBundle(Bundle bundle, String uri, InputStream is) throws BundleException {
             throw new UnsupportedOperationException();
         }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/6d298958/util/src/main/java/org/apache/karaf/util/bundles/BundleUtils.java
----------------------------------------------------------------------
diff --git a/util/src/main/java/org/apache/karaf/util/bundles/BundleUtils.java b/util/src/main/java/org/apache/karaf/util/bundles/BundleUtils.java
new file mode 100644
index 0000000..4b44b65
--- /dev/null
+++ b/util/src/main/java/org/apache/karaf/util/bundles/BundleUtils.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.util.bundles;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.osgi.framework.Constants;
+
+public class BundleUtils {
+
+    public static File fixBundleWithUpdateLocation(InputStream is, String uri) throws IOException {
+        File file = File.createTempFile("update-", ".jar");
+        try (ZipInputStream zis = new ZipInputStream(is);
+                ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file))) {
+
+            byte[] buf = new byte[8192];
+            zos.setLevel(0);
+            while (true) {
+                ZipEntry entry = zis.getNextEntry();
+                if (entry == null) {
+                    break;
+                }
+                zos.putNextEntry(entry);
+                if (entry.getName().equals(JarFile.MANIFEST_NAME)) {
+                    Manifest man = new Manifest(zis);
+                    if (man.getMainAttributes().getValue(Constants.BUNDLE_UPDATELOCATION) == null) {
+                        man.getMainAttributes().putValue(Constants.BUNDLE_UPDATELOCATION, uri);
+                    }
+                    man.write(zos);
+                } else {
+                    int n;
+                    while (-1 != (n = zis.read(buf))) {
+                        zos.write(buf, 0, n);
+                    }
+                }
+                zis.closeEntry();
+                zos.closeEntry();
+            }
+        }
+        return file;
+    }
+
+}