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 2009/09/17 15:37:10 UTC
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...
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");