You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/11/14 14:45:13 UTC

svn commit: r714001 - in /incubator/sling/trunk/extensions/jcrinstall/src: main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ main/java/org/apache/sling/jcr/jcrinstall/osgi/ main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ test/java/org/apache/sli...

Author: bdelacretaz
Date: Fri Nov 14 05:45:12 2008
New Revision: 714001

URL: http://svn.apache.org/viewvc?rev=714001&view=rev
Log:
SLING-733 - Process resource detection and installation in sequence instead of asynchronously

Modified:
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java?rev=714001&r1=714000&r2=714001&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java Fri Nov 14 05:45:12 2008
@@ -284,7 +284,7 @@
                             final Node parent = n.getParent();
                             if(!folderNameFilter.accept(parent.getPath())) {
                                 log.info("Uninstalling resource {}, folder name not accepted by current filter", uri);
-                                osgiController.uninstall(uri);
+                                osgiController.scheduleUninstall(uri);
                             }
                         }
                     }
@@ -359,11 +359,16 @@
     
     /** Let our WatchedFolders run their scanning cycles */ 
     void runOneCycle() throws Exception {
-    	boolean forceScan = false;
+    	
+    	// Add any new watched folders, and scan those who need it 
         addNewWatchedFolders();
     	for(WatchedFolder wf : folders) {
     		wf.scanIfNeeded(converters);
         }
+    	
+    	// And then let the OsgiController install/remove
+    	// resources that we detected
+    	osgiController.executeScheduledOperations();
     }
     
     Properties loadProperties(File f) {

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java?rev=714001&r1=714000&r2=714001&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java Fri Nov 14 05:45:12 2008
@@ -195,7 +195,7 @@
                     log.info("Resource {} has been deleted, uninstalling", uri);
             		// a single failure must not block the whole thing (SLING-655)
                     try {
-                    	controller.uninstall(uri);
+                    	controller.scheduleUninstall(uri);
                     } catch(JcrInstallException jie) {
                     	log.warn("Failed to uninstall " + uri, jie);
                     }
@@ -229,10 +229,10 @@
     	final String digest = controller.getDigest(path);
     	if(digest == null) {
     		log.info("Resource {} was not installed yet, installing in OsgiController", path);
-    		controller.installOrUpdate(path, fdp);
+    		controller.scheduleInstallOrUpdate(path, fdp);
     	} else if(!digest.equals(fdp.getDigest())) {
     		log.info("Resource {} has been updated, updating in OsgiController", path);
-    		controller.installOrUpdate(path, fdp);
+    		controller.scheduleInstallOrUpdate(path, fdp);
     	} else {
     		log.info("Resource {} not modified, ignoring", path);
     	}

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java?rev=714001&r1=714000&r2=714001&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java Fri Nov 14 05:45:12 2008
@@ -27,19 +27,19 @@
  */
 public interface OsgiController {
     
-    /** Install or update supplied resource 
+    /** Schedule installation or update of supplied resource 
      *  @param uri Unique identifier for the resource
      *  @param data The data to install
      *  @return one of the {@link InstallResultCode} result codes. 
      */
-    int installOrUpdate(String uri, InstallableData data) throws IOException, JcrInstallException;
+    int scheduleInstallOrUpdate(String uri, InstallableData data) throws IOException, JcrInstallException;
     
-    /** Uninstall the data that was installed via given uri
+    /** Schedule uninstallation of resource that was installed via given uri
      *  @param uri Unique identifier for the resource
      *  @param attributes metadata stored by the OsgiController, will be
      *      removed after calling this method
      */
-    void uninstall(String uri) throws JcrInstallException;
+    void scheduleUninstall(String uri) throws JcrInstallException;
     
     /** Return the list of uri for resources that have been installed 
      *  by this controller.
@@ -54,4 +54,7 @@
     
     /** Optionally set ResourceOverrideRules */
     void setResourceOverrideRules(ResourceOverrideRules r);
+    
+    /** Do the actual installs/uninistalls which were scheduled by the other methods */
+    void executeScheduledOperations() throws Exception;
 }

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=714001&r1=714000&r2=714001&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 Fri Nov 14 05:45:12 2008
@@ -52,13 +52,11 @@
  *      name="service.vendor"
  *      value="The Apache Software Foundation"
 */
-public class OsgiControllerImpl implements OsgiController, Runnable, SynchronousBundleListener {
+public class OsgiControllerImpl implements OsgiController, SynchronousBundleListener {
 
     private Storage storage;
     private List<OsgiResourceProcessor> processors;
     private final Logger log = LoggerFactory.getLogger(this.getClass());
-    private boolean running;
-    private long loopDelay;
     private ResourceOverrideRules roRules;
 
     public static final String STORAGE_FILENAME = "controller.storage";
@@ -76,22 +74,17 @@
     public static final long LAST_MODIFIED_NOT_FOUND = -1;
 
     protected void activate(ComponentContext context) throws IOException {
+    	
+    	// Note that, in executeScheduledOperations(),
+    	// processors are called in the order of this list
         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();
@@ -110,7 +103,7 @@
         processors = null;
     }
     
-    public int installOrUpdate(String uri, InstallableData data) throws IOException, JcrInstallException {
+    public int scheduleInstallOrUpdate(String uri, InstallableData data) throws IOException, JcrInstallException {
         int result = IGNORED;
         
         // If a corresponding higher priority resource is already installed, ignore this one
@@ -130,7 +123,7 @@
                 if(storage.contains(r)) {
                     log.info("Resource {} overrides {}, uninstalling the latter",
                             uri, r);
-                    uninstall(uri);
+                    scheduleUninstall(uri);
                 }
             }
         }
@@ -154,7 +147,7 @@
         return result;
     }
 
-    public void uninstall(String uri) throws JcrInstallException {
+    public void scheduleUninstall(String uri) throws JcrInstallException {
         // If a corresponding higher priority resource is installed, ignore this request
         if(roRules != null) {
             for(String r : roRules.getHigherPriorityResources(uri)) {
@@ -229,34 +222,14 @@
         //loopDelay = 0;
     }
 
-    /** Process our resource queues at regular intervals, more often if
-     *  we received bundle events since the last processing
-     */
-    public void run() {
-        log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
-
-        // We could use the scheduler service but that makes things harder to test
-        while (running) {
-            loopDelay = 1000;
-            try {
-                for(OsgiResourceProcessor p : processors) {
-                    p.processResourceQueue();
-                }
-            } catch (Exception e) {
-                log.warn("Exception in run()", e);
-            } finally {
-                try {
-                    Thread.sleep(loopDelay);
-                } catch (InterruptedException ignore) {
-                    // ignore
-                }
-            }
+    /** {@inheritDoc} */
+    public void executeScheduledOperations() throws Exception {
+        for(OsgiResourceProcessor p : processors) {
+            p.processResourceQueue();
         }
+	}
 
-        log.info("{} thread {} ends", getClass().getSimpleName(), Thread.currentThread().getName());
-    }
-    
-    public void setResourceOverrideRules(ResourceOverrideRules r) {
+	public void setResourceOverrideRules(ResourceOverrideRules r) {
         roRules = r;
     }
 }
\ No newline at end of file

Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java?rev=714001&r1=714000&r2=714001&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java Fri Nov 14 05:45:12 2008
@@ -104,6 +104,7 @@
         // Define the whole sequence of calls to OsgiController,
         // Using getLastModified calls to mark the test phases
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             
@@ -111,7 +112,7 @@
             inSequence(sequence);
             one(c).getDigest(dummyJar); will(returnValue(null));
             inSequence(sequence);
-            one(c).installOrUpdate(with(equal(dummyJar)), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(dummyJar)), with(any(InstallableData.class)));
             inSequence(sequence);
             
             one(c).getDigest("phase2"); 
@@ -123,7 +124,7 @@
             inSequence(sequence);
             one(c).getDigest(dummyJar); will(returnValue(da.getDigest()));
             inSequence(sequence);
-            one(c).installOrUpdate(with(equal(dummyJar)), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(dummyJar)), with(any(InstallableData.class)));
             inSequence(sequence);
         }});
         
@@ -167,12 +168,13 @@
         
         // Define the whole sequence of calls to OsgiController,
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).installOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
         }});
         
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
@@ -209,12 +211,13 @@
         final OsgiController c = mockery.mock(OsgiController.class);
         
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).installOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
         }});
         
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
@@ -244,12 +247,13 @@
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
         
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).uninstall("/libs/foo/bar/install/dummy.jar");
-            one(c).uninstall("/libs/foo/bar/install/dummy.cfg");
-            one(c).uninstall("/libs/watchfolder-is-gone/install/gone.cfg");
+            one(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
+            one(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
+            one(c).scheduleUninstall("/libs/watchfolder-is-gone/install/gone.cfg");
         }});
         
         ro.activate(null);
@@ -269,15 +273,16 @@
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
         
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).uninstall("/libs/foo/bar/install/dummy.cfg");
+            one(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
             inSequence(sequence);
-            one(c).uninstall("/libs/foo/bar/install/dummy.dp");
+            one(c).scheduleUninstall("/libs/foo/bar/install/dummy.dp");
             inSequence(sequence);
             will(throwException(new JcrInstallException("Fake BundleException for testing")));
-            one(c).uninstall("/libs/foo/bar/install/dummy.jar");
+            one(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
             inSequence(sequence);
         }});
         
@@ -303,13 +308,14 @@
         
         // Define the whole sequence of calls to OsgiController,
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).installOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
             will(throwException(new JcrInstallException("Fake BundleException for testing")));
-            one(c).installOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
         }});
         
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
@@ -350,11 +356,12 @@
         
         // Test with first regexp
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).installOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
         }});
         
         final MockRepositoryObserver ro = new MockRepositoryObserver(repo, c, serviceDataFile);
@@ -373,13 +380,14 @@
         
         // Test with a different regexp, install.A resources must be uninstalled
         mockery.checking(new Expectations() {{
+        	allowing(c).executeScheduledOperations();
             allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
             allowing(c).getInstalledUris(); will(returnValue(installedUri));
             allowing(c).getDigest(with(any(String.class))); will(returnValue(null)); 
-            one(c).uninstall(resources[0]);
-            one(c).uninstall(resources[2]);
-            one(c).installOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
-            one(c).installOrUpdate(with(equal(resources[3])), with(any(InstallableData.class)));
+            one(c).scheduleUninstall(resources[0]);
+            one(c).scheduleUninstall(resources[2]);
+            one(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
+            one(c).scheduleInstallOrUpdate(with(equal(resources[3])), with(any(InstallableData.class)));
         }});
         
         props.setProperty(RepositoryObserver.FOLDER_NAME_REGEXP_PROPERTY, ".*foo/wii/install$");

Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java?rev=714001&r1=714000&r2=714001&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java Fri Nov 14 05:45:12 2008
@@ -108,25 +108,25 @@
         Utilities.setProcessors(c, p);
         assertFalse("Before install, uri must not be in list", c.getInstalledUris().contains(uri));
 
-        assertEquals("First install returns INSTALLED", INSTALLED, c.installOrUpdate(uri, data));
+        assertEquals("First install returns INSTALLED", INSTALLED, c.scheduleInstallOrUpdate(uri, data));
         assertTrue("After install, uri must be in list", c.getInstalledUris().contains(uri));
         assertEquals("Digest must have been stored", data.getDigest(), c.getDigest(uri));
         assertEquals("Storage data has been saved during install", 1, s.saveCounter);
 
         data.setDigest("digest is now different");
-        assertEquals("Second install returns UPDATED", UPDATED, c.installOrUpdate(uri, data));
+        assertEquals("Second install returns UPDATED", UPDATED, c.scheduleInstallOrUpdate(uri, data));
         assertTrue("After update, uri must be in list", c.getInstalledUris().contains(uri));
         assertEquals("Digest must have been updated", data.getDigest(), c.getDigest(uri));
         assertEquals("Storage data has been saved during update", 2, s.saveCounter);
 
-        c.uninstall(uri);
+        c.scheduleUninstall(uri);
         assertFalse("After uninstall, uri must not be in list", c.getInstalledUris().contains(uri));
         assertEquals("Digest must be gone", null, c.getDigest(uri));
         assertFalse("After getLastModified, uri must not be in list", c.getInstalledUris().contains(uri));
         assertEquals("Storage data has been saved during uninstall", 3, s.saveCounter);
 
         final String nonJarUri = "no_jar_extension";
-        assertEquals(nonJarUri + " must be ignored", c.installOrUpdate("", data), IGNORED);
+        assertEquals(nonJarUri + " must be ignored", c.scheduleInstallOrUpdate("", data), IGNORED);
 
         // And verify expectations
         mockery.assertIsSatisfied();