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/18 14:51:06 UTC
svn commit: r816609 - in /sling/trunk/installer/osgi/installer/src:
main/java/org/apache/sling/osgi/installer/impl/
test/java/org/apache/sling/osgi/installer/impl/
Author: bdelacretaz
Date: Fri Sep 18 12:51:05 2009
New Revision: 816609
URL: http://svn.apache.org/viewvc?rev=816609&view=rev
Log:
SLING-1078 - store bundle digests in a single file
Added:
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java (with props)
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java (with props)
Modified:
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
Added: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java?rev=816609&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java (added)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java Fri Sep 18 12:51:05 2009
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.osgi.installer.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.TreeSet;
+
+import org.osgi.service.log.LogService;
+
+/** Store bundle digests in a file, to avoid re-installing
+ * snapshots needlessly when restarting.
+ */
+class BundleDigestsStorage {
+ private Properties digests = new Properties();
+ private final File dataFile;
+ private final OsgiInstallerContext ctx;
+
+ /** Load the list from supplied file, which is also
+ * used by purgeAndSave to save our data
+ */
+ BundleDigestsStorage(OsgiInstallerContext ctx, File dataFile) throws IOException {
+ this.ctx = ctx;
+ this.dataFile = dataFile;
+ InputStream is = null;
+ try {
+ is = new FileInputStream(dataFile);
+ digests.load(is);
+ if(ctx.getLogService() != null) {
+ ctx.getLogService().log(LogService.LOG_INFO, "Digests restored from data file " + dataFile.getName());
+ }
+ } catch(IOException ioe) {
+ if(ctx.getLogService() != null) {
+ ctx.getLogService().log(LogService.LOG_INFO,
+ "No digests retrieved, cannot read properties file " + dataFile.getName());
+ }
+ } finally {
+ if(is != null) {
+ is.close();
+ }
+ }
+ }
+
+ /** Remove digests which do not belong to installed bundles,
+ * and save our data
+ */
+ void purgeAndSave(TreeSet<String> installedBundlesSymbolicNames) throws IOException {
+ final List<String> toRemove = new ArrayList<String>();
+ for(Object o : digests.keySet()) {
+ final String key = (String)o;
+ if(!installedBundlesSymbolicNames.contains(key)) {
+ toRemove.add(key);
+ }
+ }
+ for(String key : toRemove) {
+ digests.remove(key);
+ }
+
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(dataFile);
+ digests.store(os, "Stored by " + getClass().getName());
+ } finally {
+ if(os != null) {
+ os.flush();
+ os.close();
+ }
+ }
+ if(ctx.getLogService() != null) {
+ ctx.getLogService().log(LogService.LOG_INFO,
+ "Stored digests of " + digests.size() + " bundles in data file " + dataFile.getName());
+ }
+ }
+
+ /** Store a bundle digest - not persisted until purgeAndSave is called */
+ void putDigest(String bundleSymbolicName, String digest) {
+ digests.setProperty(bundleSymbolicName, digest);
+ }
+
+ /** Retrieve digest, null if not found */
+ String getDigest(String bundleSymbolicName) {
+ return digests.getProperty(bundleSymbolicName);
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorage.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
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=816609&r1=816608&r2=816609&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 Fri Sep 18 12:51:05 2009
@@ -18,19 +18,14 @@
*/
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 java.util.TreeSet;
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;
@@ -48,9 +43,8 @@
private final ServiceTracker logServiceTracker;
private final OsgiInstallerThread installerThread;
private long [] counters = new long[COUNTERS_SIZE];
+ private BundleDigestsStorage bundleDigestsStorage;
- public static String BUNDLE_DIGEST_PREFIX = "bundle-digest-";
-
public OsgiInstallerImpl(final BundleContext bc,
final PackageAdmin pa,
final ServiceTracker logServiceTracker)
@@ -58,15 +52,22 @@
this.bundleContext = bc;
this.packageAdmin = pa;
this.logServiceTracker = logServiceTracker;
+ bundleDigestsStorage = new BundleDigestsStorage(this, bc.getDataFile("bundle-digests.properties"));
installerThread = new OsgiInstallerThread(this);
installerThread.setDaemon(true);
installerThread.start();
}
- public void deactivate() throws InterruptedException {
+ public void deactivate() throws InterruptedException, IOException {
installerThread.deactivate();
+ final TreeSet<String> installedBundlesSymbolicNames = new TreeSet<String>();
+ for(Bundle b : bundleContext.getBundles()) {
+ installedBundlesSymbolicNames.add(b.getSymbolicName());
+ }
+ bundleDigestsStorage.purgeAndSave(installedBundlesSymbolicNames);
+
if(getLogService() != null) {
getLogService().log(LogService.LOG_INFO, "Waiting for installer thread to stop");
}
@@ -172,35 +173,13 @@
}
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();
- }
+ if(bundleDigestsStorage == null) {
+ return null;
}
- return result;
+ return bundleDigestsStorage.getDigest(b.getSymbolicName());
}
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);
+ bundleDigestsStorage.putDigest(b.getSymbolicName(), digest);
}
-}
\ No newline at end of file
+ }
\ No newline at end of file
Added: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java?rev=816609&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java (added)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java Fri Sep 18 12:51:05 2009
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.osgi.installer.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.TreeSet;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class BundleDigestsStorageTest {
+ private BundleDigestsStorage storage;
+ private File testFile;
+ private TreeSet<String> installedBundles;
+
+ @Before
+ public void setUp() throws Exception {
+ testFile = File.createTempFile(getClass().getSimpleName(), "properties");
+ testFile.deleteOnExit();
+ storage = new BundleDigestsStorage(new MockOsgiInstallerContext(), testFile);
+ installedBundles = new TreeSet<String>();
+ }
+
+ @Test
+ public void testCloseAndReopen() throws IOException {
+ storage.putDigest("foo", "bar");
+ assertEquals("Before save, expecting bar digest", "bar", storage.getDigest("foo"));
+ installedBundles.add("foo");
+ storage.purgeAndSave(installedBundles);
+ assertEquals("After save, expecting bar digest", "bar", storage.getDigest("foo"));
+ storage.putDigest("foo", "wii");
+ assertEquals("After change, expecting wii digest", "wii", storage.getDigest("foo"));
+ storage = null;
+ final BundleDigestsStorage copy = new BundleDigestsStorage(new MockOsgiInstallerContext(), testFile);
+ assertEquals("In copy saved before change, expecting bar digest", "bar", copy.getDigest("foo"));
+ }
+
+ @Test
+ public void testPurge() throws IOException {
+ for(int i=0; i < 50; i++) {
+ storage.putDigest("foo" + i, "bar" + i);
+ if(i % 2 == 0) {
+ installedBundles.add("foo" + i);
+ }
+ }
+ for(int i=0; i < 50; i++) {
+ assertEquals("Before save, expecting digest to match at step " + i, "bar" + i, storage.getDigest("foo" + i));
+ }
+ storage.purgeAndSave(installedBundles);
+ for(int i=0; i < 50; i++) {
+ if(i % 2 != 0) {
+ assertNull("After purge, expecting null digest at step " + i, storage.getDigest("foo" + i));
+ } else {
+ assertEquals("After purge, expecting digest to match at step " + i, "bar" + i, storage.getDigest("foo" + i));
+ }
+ }
+ storage = null;
+ final BundleDigestsStorage copy = new BundleDigestsStorage(new MockOsgiInstallerContext(), testFile);
+ for(int i=0; i < 50; i++) {
+ if(i % 2 != 0) {
+ assertNull("In copy, expecting null digest at step " + i, copy.getDigest("foo" + i));
+ } else {
+ assertEquals("In copy, expecting digest to match at step " + i, "bar" + i, copy.getDigest("foo" + i));
+ }
+ }
+ }
+ }
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleDigestsStorageTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL