You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2015/11/03 06:28:55 UTC

[1/2] karaf git commit: https://issues.apache.org/jira/browse/KARAF-3443

Repository: karaf
Updated Branches:
  refs/heads/master dc607986e -> 025b6fb44


https://issues.apache.org/jira/browse/KARAF-3443

collects kars with unresolved dependencies to retry them during the next
deployment or after a short timeout

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

Branch: refs/heads/master
Commit: 924ffa9d387a9359398fc63c3a37dff5304ce773
Parents: 9b181c8
Author: Johannes Utzig <ju...@googlemail.com>
Authored: Fri Jul 17 23:22:17 2015 +0200
Committer: Johannes Utzig <ju...@googlemail.com>
Committed: Sat Jul 18 00:28:40 2015 +0200

----------------------------------------------------------------------
 .../karaf/kar/internal/KarServiceImpl.java      | 124 +++++++++++++++++--
 1 file changed, 116 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/924ffa9d/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
----------------------------------------------------------------------
diff --git a/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java b/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
index 3f760f9..be59b39 100644
--- a/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
@@ -32,12 +32,16 @@ import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
@@ -66,6 +70,9 @@ public class KarServiceImpl implements KarService {
     private FeaturesService featuresService;
     
     private boolean noAutoRefreshBundles;
+    private List<Kar> unsatisfiedKars;
+    private AtomicBoolean busy;
+    private DelayedDeployerThread delayedDeployerThread;
 
     public KarServiceImpl(String karafBase, FeaturesService featuresService) {
         this.base = new File(karafBase);
@@ -75,6 +82,8 @@ public class KarServiceImpl implements KarService {
         if (!storage.isDirectory()) {
             throw new IllegalStateException("KAR storage " + storage + " is not a directory");
         }
+        unsatisfiedKars = Collections.synchronizedList(new ArrayList<Kar>());
+        busy = new AtomicBoolean();
     }
     
     @Override
@@ -87,18 +96,76 @@ public class KarServiceImpl implements KarService {
     
     @Override
     public void install(URI karUri, File repoDir, File resourceDir) throws Exception {
-        Kar kar = new Kar(karUri);
-        kar.extract(repoDir, resourceDir);
-        writeToFile(kar.getFeatureRepos(), new File(repoDir, FEATURE_CONFIG_FILE));
-        for (URI uri : kar.getFeatureRepos()) {
-            addToFeaturesRepositories(uri);
-        }
-        if (kar.isShouldInstallFeatures()) {
-            installFeatures(kar.getFeatureRepos());
+        busy.set(true);
+        try {
+            Kar kar = new Kar(karUri);
+            kar.extract(repoDir, resourceDir);
+            writeToFile(kar.getFeatureRepos(), new File(repoDir, FEATURE_CONFIG_FILE));
+            for (URI uri : kar.getFeatureRepos()) {
+                addToFeaturesRepositories(uri);
+            }
+            
+            if (kar.isShouldInstallFeatures()) {
+                List<URI> featureRepos = kar.getFeatureRepos();
+                Dependency missingDependency = findMissingDependency(featureRepos);
+                if(missingDependency==null) {
+                    installFeatures(featureRepos);              
+                }
+                else {
+                    LOGGER.warn("Feature dependency {} is not available. Kar deployment postponed to see if it is about to be deployed",missingDependency);
+                    unsatisfiedKars.add(kar);
+                    if(delayedDeployerThread==null) {
+                        delayedDeployerThread = new DelayedDeployerThread();                        
+                        delayedDeployerThread.start();
+                    }
+                }
+            }
+            if(!unsatisfiedKars.isEmpty()) {
+                for (Iterator<Kar> iterator = unsatisfiedKars.iterator(); iterator.hasNext();) {
+                    Kar delayedKar = iterator.next();
+                    if(findMissingDependency(delayedKar.getFeatureRepos())==null) {
+                        LOGGER.info("Dependencies of kar {} are now satisfied. Installing",delayedKar.getKarName());
+                        iterator.remove();
+                        installFeatures(delayedKar.getFeatureRepos());
+                    }
+                }
+            }
+            if(unsatisfiedKars.isEmpty()) {
+                if(delayedDeployerThread!=null) {
+                    delayedDeployerThread.cancel();                 
+                }
+                delayedDeployerThread = null;
+            }
+        } finally {
+            busy.set(false);
         }
 
     }
 
+    /**
+     * checks if all required features are available
+     * @param featureRepos the repositories within the kar
+     * @return <code>null</code> if the contained features have no unresolvable dependencies. Otherwise the first missing dependency
+     * @throws Exception
+     */
+    private Dependency findMissingDependency(List<URI> featureRepos)
+            throws Exception {
+        for (URI uri : featureRepos) {
+            Feature[] includedFeatures = featuresService.getRepository(uri).getFeatures();
+            for (Feature includedFeature : includedFeatures) {
+                List<Dependency> dependencies = includedFeature.getDependencies();
+                for (Dependency dependency : dependencies) {
+                    Feature feature = featuresService.getFeature(dependency.getName(), dependency.getVersion());
+                    if(feature==null)
+                    {
+                        return dependency;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
 
     private List<URI> readFromFile(File repoListFile) {
         ArrayList<URI> uriList = new ArrayList<URI>();
@@ -382,4 +449,45 @@ public class KarServiceImpl implements KarService {
         this.noAutoRefreshBundles = noAutoRefreshBundles;
     }
 
+    private class DelayedDeployerThread extends Thread
+    {
+        private AtomicBoolean cancel;
+        
+        public DelayedDeployerThread() {
+            super("Delayed kar deployment");
+            cancel = new AtomicBoolean();
+        }
+        
+        public void cancel() {
+            cancel.set(true);
+        }
+        
+        @Override
+        public void run() {
+            
+            try {
+                while(busy.get() && !cancel.get()) {
+                    Thread.sleep(TimeUnit.SECONDS.toMillis(2));
+                }
+            } catch (InterruptedException e) {
+                // nothing to do
+            }
+            if (!cancel.get()) {
+                installDelayedKars();
+            }
+        }
+
+        private void installDelayedKars() {
+            for (Iterator<Kar> iterator = unsatisfiedKars.iterator(); iterator.hasNext();) {
+                Kar kar = iterator.next();
+                iterator.remove();
+                try {   
+                    installFeatures(kar.getFeatureRepos());
+                } catch (Exception e) {
+                    LOGGER.error("Delayed deployment of kar "+kar.getKarName()+" failed",e);
+                }
+            }
+        }
+    }
+
 }


[2/2] karaf git commit: Merge branch 'topic/KARAF-3443' of https://github.com/jutzig/karaf

Posted by jb...@apache.org.
Merge branch 'topic/KARAF-3443' of https://github.com/jutzig/karaf


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

Branch: refs/heads/master
Commit: 025b6fb4476c21963ba3962a6d621548853359b2
Parents: dc60798 924ffa9
Author: Jean-Baptiste Onofré <jb...@apache.org>
Authored: Mon Nov 2 20:32:07 2015 +0100
Committer: Jean-Baptiste Onofré <jb...@apache.org>
Committed: Mon Nov 2 20:32:07 2015 +0100

----------------------------------------------------------------------
 .../karaf/kar/internal/KarServiceImpl.java      | 124 +++++++++++++++++--
 1 file changed, 116 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/025b6fb4/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
----------------------------------------------------------------------
diff --cc kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
index 2b7d7d4,be59b39..1b73165
--- a/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
+++ b/kar/src/main/java/org/apache/karaf/kar/internal/KarServiceImpl.java
@@@ -66,10 -70,13 +70,13 @@@ public class KarServiceImpl implements 
      private FeaturesService featuresService;
      
      private boolean noAutoRefreshBundles;
+     private List<Kar> unsatisfiedKars;
+     private AtomicBoolean busy;
+     private DelayedDeployerThread delayedDeployerThread;
  
 -    public KarServiceImpl(String karafBase, FeaturesService featuresService) {
 +    public KarServiceImpl(String karafBase, String karafData, FeaturesService featuresService) {
          this.base = new File(karafBase);
 -        this.storage = new File(this.base, "data" + File.separator + "kar");
 +        this.storage = new File(new File(karafData), "kar");
          this.featuresService = featuresService;
          this.storage.mkdirs();
          if (!storage.isDirectory()) {