Return-Path: Delivered-To: apmail-sling-commits-archive@www.apache.org Received: (qmail 56230 invoked from network); 17 Sep 2009 13:37:37 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 17 Sep 2009 13:37:37 -0000 Received: (qmail 20958 invoked by uid 500); 17 Sep 2009 13:37:37 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 20900 invoked by uid 500); 17 Sep 2009 13:37:36 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 20891 invoked by uid 99); 17 Sep 2009 13:37:36 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Sep 2009 13:37:36 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 17 Sep 2009 13:37:32 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 49FC82388965; Thu, 17 Sep 2009 13:37:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r816185 - in /sling/trunk/installer/osgi: installer/src/main/java/org/apache/sling/osgi/installer/impl/ installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/ installer/src/test/java/org/apache/sling/osgi/installer/impl/ it/src... Date: Thu, 17 Sep 2009 13:37:10 -0000 To: commits@sling.apache.org From: bdelacretaz@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090917133711.49FC82388965@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: bdelacretaz Date: Thu Sep 17 13:37:09 2009 New Revision: 816185 URL: http://svn.apache.org/viewvc?rev=816185&view=rev Log: SLING-1078 - store bundle digests to avoid unnecessary snapshot updates Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerContext.java sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockOsgiInstallerContext.java sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleSnapshotUpdateTest.java sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerContext.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerContext.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerContext.java (original) +++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerContext.java Thu Sep 17 13:37:09 2009 @@ -18,6 +18,8 @@ */ package org.apache.sling.osgi.installer.impl; +import java.io.IOException; + import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Version; @@ -43,4 +45,12 @@ * usually to indicate that a task must be retried */ void addTaskToNextCycle(OsgiInstallerTask t); + + /** Store a bundle's digest, keyed by symbolic ID + version */ + void saveBundleDigest(Bundle b, String digest) throws IOException; + + /** Retrieve a bundle's digest that was stored by storeBundleDigest + * @return null if no digest was stored + * */ + String getBundleDigest(Bundle b) throws IOException; } Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java (original) +++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java Thu Sep 17 13:37:09 2009 @@ -18,13 +18,19 @@ */ package org.apache.sling.osgi.installer.impl; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; +import java.io.PrintWriter; import java.util.Collection; import org.apache.sling.osgi.installer.InstallableResource; import org.apache.sling.osgi.installer.OsgiInstaller; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.Version; import org.osgi.service.cm.ConfigurationAdmin; @@ -42,6 +48,8 @@ private final ServiceTracker logServiceTracker; private final OsgiInstallerThread installerThread; private long [] counters = new long[COUNTERS_SIZE]; + + public static String BUNDLE_DIGEST_PREFIX = "bundle-digest-"; public OsgiInstallerImpl(final BundleContext bc, final PackageAdmin pa, @@ -56,8 +64,14 @@ installerThread.start(); } - public void deactivate() { + public void deactivate() throws InterruptedException { installerThread.deactivate(); + + if(getLogService() != null) { + getLogService().log(LogService.LOG_INFO, "Waiting for installer thread to stop"); + } + installerThread.join(); + if(getLogService() != null) { getLogService().log(LogService.LOG_WARNING, OsgiInstaller.class.getName() @@ -156,4 +170,37 @@ public boolean isSnapshot(Version v) { return v.toString().indexOf(MAVEN_SNAPSHOT_MARKER) >= 0; } + + public String getBundleDigest(Bundle b) throws IOException { + // TODO it would be cleaner to use a single file to + // store those digests - and currently digests files + // are not purged + String result = null; + final File f = getBundleDigestFile(b); + if(f.exists()) { + final FileReader fr = new FileReader(f); + try { + result = new BufferedReader(fr).readLine(); + } finally { + fr.close(); + } + } + return result; + } + + public void saveBundleDigest(Bundle b, String digest) throws IOException { + final File f = getBundleDigestFile(b); + final FileWriter fw = new FileWriter(f); + try { + new PrintWriter(fw).write(digest); + } finally { + fw.close(); + } + } + + private File getBundleDigestFile(Bundle b) { + final String version = (String)b.getHeaders().get(Constants.BUNDLE_VERSION); + final String filename = BUNDLE_DIGEST_PREFIX + b.getSymbolicName() + version + ".txt"; + return bundleContext.getDataFile(filename); + } } \ No newline at end of file Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java (original) +++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java Thu Sep 17 13:37:09 2009 @@ -41,6 +41,7 @@ public void execute(OsgiInstallerContext ctx) throws Exception { final Bundle b = ctx.getBundleContext().installBundle(resource.getUrl(), resource.getInputStream()); + ctx.saveBundleDigest(b, resource.getDigest()); logExecution(ctx); ctx.addTaskToCurrentCycle(new BundleStartTask(b.getBundleId())); ctx.incrementCounter(OsgiInstaller.OSGI_TASKS_COUNTER); Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java (original) +++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java Thu Sep 17 13:37:09 2009 @@ -57,10 +57,12 @@ } // Do not update if same version, unless snapshot + boolean snapshot = false; if(b != null) { final Version currentVersion = new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION)); final Version newVersion = (Version)resource.getAttributes().get(Constants.BUNDLE_VERSION); - if(currentVersion.equals(newVersion) && !ctx.isSnapshot(newVersion)) { + snapshot = ctx.isSnapshot(newVersion); + if(currentVersion.equals(newVersion) && !snapshot) { if(ctx.getLogService() != null) { ctx.getLogService().log( LogService.LOG_DEBUG, @@ -70,6 +72,21 @@ } } + // If snapshot and ready to update, cancel if digest didn't change - as the list + // of RegisteredResources is not saved, this might not have been detected earlier, + // if the snapshot was installed and the installer was later restarted + if( (b != null) && snapshot) { + final String oldDigest = ctx.getBundleDigest(b); + if(resource.getDigest().equals(oldDigest)) { + if(ctx.getLogService() != null) { + ctx.getLogService().log( + LogService.LOG_DEBUG, + "Snapshot digest did not change, ignoring update:" + resource); + } + return; + } + } + logExecution(ctx); if(b.getState() == Bundle.ACTIVE) { // bundle was active before the update - restart it once updated, but @@ -78,6 +95,7 @@ } b.stop(); b.update(resource.getInputStream()); + ctx.saveBundleDigest(b, resource.getDigest()); if(ctx.getLogService() != null) { ctx.getLogService().log(LogService.LOG_DEBUG, "Bundle updated: " + b.getBundleId() + "/" + b.getSymbolicName()); } @@ -89,4 +107,4 @@ return TaskOrder.BUNDLE_UPDATE_ORDER + resource.getUrl(); } -} +} \ No newline at end of file Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockOsgiInstallerContext.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockOsgiInstallerContext.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockOsgiInstallerContext.java (original) +++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockOsgiInstallerContext.java Thu Sep 17 13:37:09 2009 @@ -18,6 +18,8 @@ */ package org.apache.sling.osgi.installer.impl; +import java.io.IOException; + import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Version; @@ -62,4 +64,11 @@ public boolean isSnapshot(Version v) { return v.toString().indexOf(OsgiInstallerImpl.MAVEN_SNAPSHOT_MARKER) >= 0; } + + public String getBundleDigest(Bundle b) throws IOException { + return null; + } + + public void saveBundleDigest(Bundle b, String digest) throws IOException { + } } Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleSnapshotUpdateTest.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleSnapshotUpdateTest.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleSnapshotUpdateTest.java (original) +++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleSnapshotUpdateTest.java Thu Sep 17 13:37:09 2009 @@ -30,6 +30,7 @@ import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.JUnit4TestRunner; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleException; /** Verify that snapshot bundles are updated even if * their version number does not change. @@ -86,8 +87,7 @@ assertNoOsgiTasks("At end of test"); } - @Test - public void testSnapshot() throws IOException { + private void testSnapshotPrimitive(boolean restartInstaller) throws IOException, BundleException { // Install test bundle final String symbolicName = "osgi-installer-snapshot-test"; @@ -100,6 +100,10 @@ final Bundle b = findBundle(symbolicName); assertNotNull("Snapshot bundle must be found after waitForInstallerAction", b); + if(restartInstaller) { + restartInstaller(); + } + // Update with same digest must be ignored final long nOps = installer.getCounters()[OsgiInstaller.OSGI_TASKS_COUNTER]; installer.addResource(getInstallableResource( @@ -118,4 +122,14 @@ // And no more OSGi tasks after that assertNoOsgiTasks("At end of test"); } -} + + @Test + public void testSnapshot() throws IOException, BundleException { + testSnapshotPrimitive(false); + } + + @Test + public void testSnapshotWithInstallerRestart() throws IOException, BundleException { + testSnapshotPrimitive(true); + } +} \ No newline at end of file Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java?rev=816185&r1=816184&r2=816185&view=diff ============================================================================== --- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java (original) +++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/OsgiInstallerTestBase.java Thu Sep 17 13:37:09 2009 @@ -40,6 +40,7 @@ import org.ops4j.pax.exam.Option; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkListener; @@ -94,6 +95,18 @@ } } + protected void restartInstaller() throws BundleException { + final String symbolicName = "org.apache.sling.osgi.installer"; + final Bundle b = findBundle(symbolicName); + if(b == null) { + fail("Bundle " + symbolicName + " not found"); + } + log(LogService.LOG_INFO, "Restarting " + symbolicName + " bundle"); + b.stop(); + b.start(); + setupInstaller(); + } + protected void generateBundleEvent() throws Exception { // install a bundle manually to generate a bundle event final File f = getTestBundle("org.apache.sling.osgi.installer.it-" + POM_VERSION + "-testbundle-1.0.jar");