incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r705191 - in /incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl: BundleResourceProcessor.java OsgiControllerImpl.java
Date Thu, 16 Oct 2008 09:58:58 GMT
Author: cziegeler
Date: Thu Oct 16 02:58:57 2008
New Revision: 705191

URL: http://svn.apache.org/viewvc?rev=705191&view=rev
Log:
SLING-699 : Synchronized bundle install/update/start/refresh, and only update bundles if the
 version number is higher. Fixed some log messages.

Modified:
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java?rev=705191&r1=705190&r2=705191&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
Thu Oct 16 02:58:57 2008
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.jcr.jcrinstall.osgi.impl;
 
+import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.IGNORED;
 import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.INSTALLED;
 import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.UPDATED;
 
@@ -37,6 +38,7 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,7 +55,6 @@
     private final PackageAdmin packageAdmin;
     private final Map<Long, Bundle> pendingBundles;
     private final Logger log = LoggerFactory.getLogger(this.getClass());
-    private final Object refreshLock = new Object();
 
     BundleResourceProcessor(BundleContext ctx, PackageAdmin packageAdmin) {
         this.ctx = ctx;
@@ -61,56 +62,80 @@
         pendingBundles = new HashMap<Long, Bundle>();
     }
 
-    public int installOrUpdate(String uri, Map<String, Object> attributes, InputStream
data) throws Exception {
+    /**
+     * @throws BundleException
+     * @see org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#installOrUpdate(java.lang.String,
java.util.Map, java.io.InputStream)
+     */
+    public int installOrUpdate(String uri, Map<String, Object> attributes, InputStream
data)
+    throws BundleException, IOException {
         // Update if we already have a bundle id, else install
         Bundle b = null;
         boolean updated = false;
 
-        // check whether we know the bundle and it exists
-        final Long longId = (Long)attributes.get(KEY_BUNDLE_ID);
-        if(longId != null) {
-            b = ctx.getBundle(longId);
-        }
+        synchronized (pendingBundles) {
+            // check whether we know the bundle and it exists
+            final Long longId = (Long)attributes.get(KEY_BUNDLE_ID);
+            if (longId != null) {
+                b = ctx.getBundle(longId);
+            }
 
-        // either we don't know the bundle yet or it does not exist,
-        // so check whether the bundle can be found by its symbolic name
-        if (b == null) {
-            // ensure we can mark and reset to read the manifest
-            if (!data.markSupported()) {
-                data = new BufferedInputStream(data);
+            // either we don't know the bundle yet or it does not exist,
+            // so check whether the bundle can be found by its symbolic name
+            if (b == null) {
+                // ensure we can mark and reset to read the manifest
+                if (!data.markSupported()) {
+                    data = new BufferedInputStream(data);
+                }
+                final BundleInfo info = getMatchingBundle(data);
+                if ( info != null ) {
+                    final Version availableVersion = new Version((String)info.bundle.getHeaders().get(Constants.BUNDLE_VERSION));
+                    final Version newVersion = new Version(info.newVersion);
+                    if ( newVersion.compareTo(availableVersion) > 0 ) {
+                        b = info.bundle;
+                    } else {
+                        log.debug("Ignore update of bundle {} from {} as the installed version
is equal or higher.", info.bundle.getSymbolicName(), uri);
+                        return IGNORED;
+                    }
+                }
             }
-            b = getMatchingBundle(data);
-        }
 
-        if (b != null) {
-            b.update(data);
-            updated = true;
-        } else {
-            uri = OsgiControllerImpl.getResourceLocation(uri);
-            log.debug("No matching Bundle for uri {}, installing", uri);
-            b = ctx.installBundle(uri, data);
-        }
+            if (b != null) {
+                b.update(data);
+                updated = true;
+                // wait a little bit after an update
+                try {
+                    Thread.sleep(1500);
+                } catch (InterruptedException e) {
+                    // ignore
+                }
+            } else {
+                uri = OsgiControllerImpl.getResourceLocation(uri);
+                log.debug("No matching Bundle for uri {}, installing", uri);
+                b = ctx.installBundle(uri, data);
+            }
 
-        // ensure the bundle id in the attributes, this may be overkill
-        // in simple update situations, but is required for installations
-        // and updates where there are no attributes yet
-        attributes.put(KEY_BUNDLE_ID, b.getBundleId());
+            // ensure the bundle id in the attributes, this may be overkill
+            // in simple update situations, but is required for installations
+            // and updates where there are no attributes yet
+            attributes.put(KEY_BUNDLE_ID, b.getBundleId());
 
-        synchronized(pendingBundles) {
             pendingBundles.put(b.getBundleId(), b);
         }
 
         return updated ? UPDATED : INSTALLED;
     }
 
+    /**
+     * @see org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#uninstall(java.lang.String,
java.util.Map)
+     */
     public void uninstall(String uri, Map<String, Object> attributes) throws BundleException
{
         final Long longId = (Long)attributes.get(KEY_BUNDLE_ID);
-        if(longId == null) {
-            log.debug("No {} in metadata, bundle cannot be uninstalled");
+        if (longId == null) {
+            log.debug("No bundle id in metadata for {}, bundle cannot be uninstalled.", uri);
         } else {
             final Bundle b = ctx.getBundle(longId);
-            if(b == null) {
-                log.debug("Bundle having id {} not found, cannot uninstall");
+            if (b == null) {
+                log.debug("Bundle having id {} not found, cannot uninstall", longId);
             } else {
                 synchronized(pendingBundles) {
                     pendingBundles.remove(b.getBundleId());
@@ -120,69 +145,76 @@
         }
     }
 
+    /**
+     * @see org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#canProcess(java.lang.String)
+     */
     public boolean canProcess(String uri) {
         return uri.endsWith(BUNDLE_EXTENSION);
     }
 
+    /**
+     * @see org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor#processResourceQueue()
+     */
     public void processResourceQueue() {
-
-        if(pendingBundles.isEmpty()) {
-            return;
-        }
-
-        final List<Long> toRemove = new LinkedList<Long>();
-        final List<Long> idList = new LinkedList<Long>();
         synchronized(pendingBundles) {
+            if (pendingBundles.isEmpty()) {
+                return;
+            }
+            final List<Long> toRemove = new LinkedList<Long>();
+            final List<Long> idList = new LinkedList<Long>();
+
             idList.addAll(pendingBundles.keySet());
-        }
 
-        for(Long id : idList) {
-            final Bundle bundle = ctx.getBundle(id);
-            if(bundle == null) {
-                log.debug("Bundle id {} disappeared (bundle removed from framework?), removed
from pending bundles queue");
-                toRemove.add(id);
-                continue;
-            }
-            final int state = bundle.getState();
-
-            switch ( state ) {
-                case Bundle.ACTIVE :
-                    log.info("Bundle {} is active, removed from pending bundles queue", bundle.getLocation());
-                    toRemove.add(id);
-                    break;
-                case Bundle.STARTING :
-                    log.info("Bundle {} is starting.", bundle.getLocation());
-                    break;
-                case Bundle.STOPPING :
-                    log.info("Bundle {} is stopping.", bundle.getLocation());
-                    break;
-                case Bundle.UNINSTALLED :
-                    log.info("Bundle {} is uninstalled, removed from pending bundles queue",
bundle.getLocation());
+            boolean doRefresh = false;
+
+            for(Long id : idList) {
+                final Bundle bundle = ctx.getBundle(id);
+                if(bundle == null) {
+                    log.debug("Bundle id {} disappeared (bundle removed from framework?),
removed from pending bundles queue", id);
                     toRemove.add(id);
-                    break;
-                case Bundle.INSTALLED :
-                    log.debug("Bundle {} is installed but not resolved.", bundle.getLocation());
-                    if ( !packageAdmin.resolveBundles(new Bundle[] {bundle}) ) {
-                        log.debug("Bundle {} is installed, failed to resolve.", bundle.getLocation());
+                    continue;
+                }
+                final int state = bundle.getState();
+
+                switch ( state ) {
+                    case Bundle.ACTIVE :
+                        log.info("Bundle {} is active, removed from pending bundles queue",
bundle.getLocation());
+                        toRemove.add(id);
                         break;
-                    }
-                    // fall through to RESOLVED to start the bundle
-                case Bundle.RESOLVED :
-                    log.info("Bundle {} is resolved, trying to start it.", bundle.getLocation());
-                    try {
-                        bundle.start();
-                    } catch (BundleException e) {
-                        log.error("Exception during bundle start of Bundle " + bundle.getLocation(),
e);
-                    }
-                    break;
+                    case Bundle.STARTING :
+                        log.info("Bundle {} is starting.", bundle.getLocation());
+                        break;
+                    case Bundle.STOPPING :
+                        log.info("Bundle {} is stopping.", bundle.getLocation());
+                        break;
+                    case Bundle.UNINSTALLED :
+                        log.info("Bundle {} is uninstalled, removed from pending bundles
queue", bundle.getLocation());
+                        toRemove.add(id);
+                        doRefresh = true;
+                        break;
+                    case Bundle.INSTALLED :
+                        log.debug("Bundle {} is installed but not resolved.", bundle.getLocation());
+                        if ( !packageAdmin.resolveBundles(new Bundle[] {bundle}) ) {
+                            log.debug("Bundle {} is installed, failed to resolve.", bundle.getLocation());
+                            break;
+                        }
+                        // fall through to RESOLVED to start the bundle
+                    case Bundle.RESOLVED :
+                        log.info("Bundle {} is resolved, trying to start it.", bundle.getLocation());
+                        try {
+                            bundle.start();
+                        } catch (BundleException e) {
+                            log.error("Exception during bundle start of Bundle " + bundle.getLocation(),
e);
+                        }
+                        doRefresh = true;
+                        break;
+                }
             }
-        }
 
-        synchronized(refreshLock) {
-            packageAdmin.refreshPackages(null);
-        }
+            if ( doRefresh ) {
+                packageAdmin.refreshPackages(null);
+            }
 
-        synchronized(pendingBundles) {
             pendingBundles.keySet().removeAll(toRemove);
         }
     }
@@ -210,7 +242,7 @@
      *         with a symbolic name.
      * @throws IOException If an error occurrs reading from the input stream.
      */
-    private Bundle getMatchingBundle(InputStream data) throws IOException {
+    private BundleInfo getMatchingBundle(InputStream data) throws IOException {
         // allow 2KB, this should be enough for the manifest
         data.mark(2048);
 
@@ -237,7 +269,10 @@
                     Bundle[] bundles = ctx.getBundles();
                     for (Bundle bundle : bundles) {
                         if (symbolicName.equals(bundle.getSymbolicName())) {
-                            return bundle;
+                            final BundleInfo info = new BundleInfo();
+                            info.bundle = bundle;
+                            info.newVersion = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+                            return info;
                         }
                     }
 
@@ -260,4 +295,9 @@
         // fall back to no bundle found for update
         return null;
     }
+
+    protected static final class BundleInfo {
+        public Bundle bundle;
+        public String newVersion;
+    }
 }
\ No newline at end of file

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java?rev=705191&r1=705190&r2=705191&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
Thu Oct 16 02:58:57 2008
@@ -39,16 +39,16 @@
 import org.slf4j.LoggerFactory;
 
 /** OsgiController service
- *  
+ *
  *  @scr.service
- *  @scr.component 
+ *  @scr.component
  *      immediate="true"
  *      metatype="no"
- *  @scr.property 
- *      name="service.description" 
+ *  @scr.property
+ *      name="service.description"
  *      value="Sling jcrinstall OsgiController Service"
- *  @scr.property 
- *      name="service.vendor" 
+ *  @scr.property
+ *      name="service.vendor"
  *      value="The Apache Software Foundation"
 */
 public class OsgiControllerImpl implements OsgiController, Runnable, SynchronousBundleListener
{
@@ -58,38 +58,38 @@
     private final Logger log = LoggerFactory.getLogger(this.getClass());
     private boolean running;
     private long loopDelay;
-    
+
     public static final String STORAGE_FILENAME = "controller.storage";
-    
+
     /** @scr.reference */
     private ConfigurationAdmin configAdmin;
-    
+
     /** @scr.reference */
     private PackageAdmin packageAdmin;
-    
+
     /** Storage key: last modified as a Long */
     public static final String KEY_LAST_MODIFIED = "last.modified";
-    
+
     /** Default value for getLastModified() */
     public static final long LAST_MODIFIED_NOT_FOUND = -1;
-    
+
     protected void activate(ComponentContext context) throws IOException {
         processors = new LinkedList<OsgiResourceProcessor>();
         processors.add(new BundleResourceProcessor(context.getBundleContext(), packageAdmin));
         processors.add(new ConfigResourceProcessor(configAdmin));
-        
+
         storage = new Storage(context.getBundleContext().getDataFile(STORAGE_FILENAME));
-        
+
         // start queue processing
         running = true;
         final Thread t = new Thread(this, getClass().getSimpleName() + "_" + System.currentTimeMillis());
         t.setDaemon(true);
         t.start();
     }
-    
+
     protected void deactivate(ComponentContext oldContext) {
         running = false;
-        
+
         if(storage != null) {
             try {
                 storage.saveToFile();
@@ -100,15 +100,15 @@
         storage = null;
         processors = null;
     }
-    
+
     public int installOrUpdate(String uri, long lastModified, InputStream data) throws IOException,
JcrInstallException {
         int result = IGNORED;
         final OsgiResourceProcessor p = getProcessor(uri);
-        if(p != null) {
+        if (p != null) {
             try {
                 final Map<String, Object> map = storage.getMap(uri);
                 result = p.installOrUpdate(uri, map, data);
-                if(result != IGNORED) {
+                if (result != IGNORED) {
                     map.put(KEY_LAST_MODIFIED, new Long(lastModified));
                 }
                 storage.saveToFile();
@@ -120,7 +120,7 @@
         }
         return result;
     }
-    
+
     public void uninstall(String uri) throws JcrInstallException {
         final OsgiResourceProcessor p = getProcessor(uri);
         if(p != null) {
@@ -133,7 +133,7 @@
             }
         }
     }
-    
+
     public Set<String> getInstalledUris() {
         return storage.getKeys();
     }
@@ -143,46 +143,46 @@
      */
     public long getLastModified(String uri) {
         long result = LAST_MODIFIED_NOT_FOUND;
-        
+
         if(storage.contains(uri)) {
             final Map<String, Object> uriData = storage.getMap(uri);
-            final Long lastMod = (Long)uriData.get(KEY_LAST_MODIFIED); 
+            final Long lastMod = (Long)uriData.get(KEY_LAST_MODIFIED);
             if(lastMod != null) {
                 result = lastMod.longValue();
             }
         }
         return result;
     }
-    
+
     static String getResourceLocation(String uri) {
         return "jcrinstall://" + uri;
     }
-    
+
     /** Return the first processor that accepts given uri, null if not found */
     OsgiResourceProcessor getProcessor(String uri) {
         OsgiResourceProcessor result = null;
-        
+
         if(processors == null) {
             throw new IllegalStateException("Processors are not set");
         }
-        
+
         for(OsgiResourceProcessor p : processors) {
             if(p.canProcess(uri)) {
                 result = p;
                 break;
             }
         }
-        
+
         if(result == null) {
             log.debug("No processor found for resource {}", uri);
         }
-        
+
         return result;
     }
-    
+
     /** Schedule our next scan sooner if anything happens to bundles */
     public void bundleChanged(BundleEvent e) {
-        loopDelay = 0;
+        //loopDelay = 0;
     }
 
     /** Process our resource queues at regular intervals, more often if
@@ -198,7 +198,7 @@
                 for(OsgiResourceProcessor p : processors) {
                     p.processResourceQueue();
                 }
-                
+
             } catch (Exception e) {
                 log.warn("Exception in run()", e);
             } finally {



Mime
View raw message