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/08/17 21:36:18 UTC
svn commit: r805111 - in /sling/trunk/installer/osgi:
installer/src/main/java/org/apache/sling/osgi/installer/
installer/src/main/java/org/apache/sling/osgi/installer/impl/
installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/
installer/s...
Author: bdelacretaz
Date: Mon Aug 17 19:36:18 2009
New Revision: 805111
URL: http://svn.apache.org/viewvc?rev=805111&view=rev
Log:
SLING-1078 - BundleTaskCreator and tests, work in progress
Added:
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java (with props)
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java (with props)
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java (with props)
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java (with props)
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java (with props)
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java (with props)
Modified:
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleTaskCreator.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/OsgiInstallerThread.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResource.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceComparator.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallRemoveTask.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskOrder.java
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskUtilities.java
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryConversionTest.java
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryDigestTest.java
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/LocalFileRegisteredResource.java
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java
sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/TaskOrderingTest.java
sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallTest.java
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/OsgiInstaller.java Mon Aug 17 19:36:18 2009
@@ -61,6 +61,9 @@
/** Counter index: number of OSGi tasks executed */
int OSGI_TASKS_COUNTER = 0;
+ /** Counter index: number of installer cycles */
+ int INSTALLER_CYCLES_COUNTER = 1;
+
/** Size of the counters array */
- int COUNTERS_SIZE = 1;
+ int COUNTERS_SIZE = 2;
}
\ No newline at end of file
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleTaskCreator.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleTaskCreator.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleTaskCreator.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/BundleTaskCreator.java Mon Aug 17 19:36:18 2009
@@ -18,16 +18,90 @@
*/
package org.apache.sling.osgi.installer.impl;
-import java.util.TreeSet;
+import java.util.SortedSet;
import org.apache.sling.osgi.installer.impl.tasks.BundleInstallTask;
+import org.apache.sling.osgi.installer.impl.tasks.BundleRemoveTask;
+import org.apache.sling.osgi.installer.impl.tasks.BundleUpdateTask;
+import org.apache.sling.osgi.installer.impl.tasks.TaskUtilities;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
/** TaskCreator that processes a list of bundle RegisteredResources */
class BundleTaskCreator implements OsgiInstallerThread.TaskCreator {
- public void createTasks(TreeSet<RegisteredResource> resources, TreeSet<OsgiInstallerTask> tasks) {
+ public static final String MAVEN_SNAPSHOT_MARKER = "SNAPSHOT";
+
+ /** Holds the bundle info that we need, makes it easier to test
+ * without an OSGi framework */
+ static class BundleInfo {
+ final Version version;
+ final int state;
+
+ BundleInfo(Version version, int state) {
+ this.version = version;
+ this.state = state;
+ }
+
+ BundleInfo(Bundle b) {
+ this.version = new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
+ this.state = b.getState();
+ }
+ }
+
+ /** Create tasks for a set of RegisteredResource that all represent the same bundle.
+ * Selects the bundle with the highest priority (i.e. the first one in the group that
+ * has desired state == active, and generates the appropriate OSGi tasks to
+ * reach this state.
+ */
+ public void createTasks(BundleContext ctx, SortedSet<RegisteredResource> resources, SortedSet<OsgiInstallerTask> tasks) {
+
+ // Find the bundle that must be active: the resources collection is ordered according
+ // to priorities, so we just need to find the first one that is installable
+ RegisteredResource toActivate = null;
for(RegisteredResource r : resources) {
- tasks.add(new BundleInstallTask(r));
+ if(toActivate == null && r.isInstallable()) {
+ toActivate = r;
+ break;
+ }
}
+
+ if(toActivate == null) {
+ // None of our resources are installable, remove corresponding bundle
+ final BundleInfo info = getBundleInfo(ctx, resources.first());
+ if(info != null) {
+ tasks.add(new BundleRemoveTask(resources.first()));
+ }
+
+ } else {
+ final BundleInfo info = getBundleInfo(ctx, toActivate);
+ final Version newVersion = (Version)toActivate.getAttributes().get(Constants.BUNDLE_VERSION);
+ if(info == null) {
+ // bundle is not installed yet
+ tasks.add(new BundleInstallTask(toActivate));
+ } else {
+ final int compare = info.version.compareTo(newVersion);
+ if(compare != 0) {
+ // installed but different version. Can be a later version if
+ // the newer version resource was removed, in case we downgrade
+ tasks.add(new BundleUpdateTask(toActivate));
+ } else if(compare == 0 && newVersion.toString().indexOf(MAVEN_SNAPSHOT_MARKER) >= 0){
+ // installed, same version but SNAPSHOT
+ // TODO: update only if not updated with same digest yet
+ tasks.add(new BundleUpdateTask(toActivate));
+ }
+ }
+ }
+ }
+
+ protected BundleInfo getBundleInfo(BundleContext ctx, RegisteredResource bundle) {
+ final String symbolicName = (String)bundle.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);
+ final Bundle b = TaskUtilities.getMatchingBundle(ctx, symbolicName);
+ if(b == null) {
+ return null;
+ }
+ return new BundleInfo(b);
}
}
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=805111&r1=805110&r2=805111&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 Mon Aug 17 19:36:18 2009
@@ -47,7 +47,12 @@
this.packageAdmin = pa;
this.logServiceTracker = logServiceTracker;
- installerThread = new OsgiInstallerThread(this);
+ installerThread = new OsgiInstallerThread(this) {
+ @Override
+ protected void cycleDone() {
+ incrementCounter(INSTALLER_CYCLES_COUNTER);
+ }
+ };
installerThread.setDaemon(true);
installerThread.start();
}
@@ -102,7 +107,7 @@
public void addResource(InstallableResource r) throws IOException {
// TODO do not add if we already have it, based on digest
- installerThread.addNewResource(new RegisteredResource(bundleContext, r));
+ installerThread.addNewResource(new RegisteredResourceImpl(bundleContext, r));
}
public void registerResources(Collection<InstallableResource> data,
@@ -110,8 +115,10 @@
// TODO
}
- public void removeResource(InstallableResource d) throws IOException {
- // TODO
+ public void removeResource(InstallableResource r) throws IOException {
+ final RegisteredResource rr = new RegisteredResourceImpl(bundleContext, r);
+ rr.setInstallable(false);
+ installerThread.addNewResource(rr);
}
public Storage getStorage() {
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerThread.java Mon Aug 17 19:36:18 2009
@@ -22,8 +22,11 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
import java.util.TreeSet;
+import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
/** Worker thread where all OSGi tasks are executed.
@@ -38,21 +41,23 @@
private final OsgiInstallerContext ctx;
private final List<RegisteredResource> newResources = new LinkedList<RegisteredResource>();
- private final TreeSet<OsgiInstallerTask> tasks = new TreeSet<OsgiInstallerTask>();
+ private final SortedSet<OsgiInstallerTask> tasks = new TreeSet<OsgiInstallerTask>();
/** Group our RegisteredResource by OSGi entity */
- private final Map<String, TreeSet<RegisteredResource>> registeredResources =
- new HashMap<String, TreeSet<RegisteredResource>>();
+ private Map<String, SortedSet<RegisteredResource>>registeredResources =
+ new HashMap<String, SortedSet<RegisteredResource>>();
+
+ private final BundleTaskCreator bundleTaskCreator = new BundleTaskCreator();
static interface TaskCreator {
/** Add the required OsgiInstallerTasks to the tasks collection, so that the resources reach
* their desired states.
+ * @param ctx used to find out which bundles and configs are currently active
* @param resources ordered set of RegisteredResource which all have the same entityId
* @param tasks lists of tasks, to which we'll add the ones computed by this method
*/
- void createTasks(TreeSet<RegisteredResource> resources, TreeSet<OsgiInstallerTask> tasks);
+ void createTasks(BundleContext ctx, SortedSet<RegisteredResource> resources, SortedSet<OsgiInstallerTask> tasks);
}
- private final TaskCreator bundleTaskCreator = new BundleTaskCreator();
OsgiInstallerThread(OsgiInstallerContext ctx) {
setName(getClass().getSimpleName());
@@ -65,9 +70,10 @@
// TODO do nothing if nothing to process!
try {
mergeNewResources();
- computeTasks();
+ computeTasks();
executeTasks();
Thread.sleep(250);
+ cycleDone();
} catch(Exception e) {
if(ctx.getLogService() != null) {
ctx.getLogService().log(LogService.LOG_WARNING, e.toString(), e);
@@ -96,33 +102,35 @@
}
}
- private void addRegisteredResource(RegisteredResource r) {
- TreeSet<RegisteredResource> t = registeredResources.get(r.getEntityId());
- if(t == null) {
- t = new TreeSet<RegisteredResource>(new RegisteredResourceComparator());
- registeredResources.put(r.getEntityId(), t);
- }
- t.add(r);
-
- }
-
private void mergeNewResources() {
synchronized (newResources) {
for(RegisteredResource r : newResources) {
- addRegisteredResource(r);
+ SortedSet<RegisteredResource> t = registeredResources.get(r.getEntityId());
+ if(t == null) {
+ t = createRegisteredResourcesEntry();
+ registeredResources.put(r.getEntityId(), t);
+ }
+ t.add(r);
}
newResources.clear();
}
}
+
+ /** Factored out to use the exact same structure in tests */
+ static SortedSet<RegisteredResource> createRegisteredResourcesEntry() {
+ return new TreeSet<RegisteredResource>(new RegisteredResourceComparator());
+ }
+
- private void computeTasks() {
+ /** Compute OSGi tasks based on our resources, and add to supplied list of tasks */
+ void computeTasks() {
// Walk the list of entities, and create appropriate OSGi tasks for each group
- for(TreeSet<RegisteredResource> group : registeredResources.values()) {
- if(group.first().getResourceType().equals(RegisteredResource.ResourceType.BUNDLE)) {
- bundleTaskCreator.createTasks(group, tasks);
- } else {
- throw new IllegalArgumentException("No TaskCreator for resource type "+ group.first().getResourceType());
- }
+ for(SortedSet<RegisteredResource> group : registeredResources.values()) {
+ if(group.first().getResourceType().equals(RegisteredResource.ResourceType.BUNDLE)) {
+ bundleTaskCreator.createTasks(ctx.getBundleContext(), group, tasks);
+ } else {
+ throw new IllegalArgumentException("No TaskCreator for resource type "+ group.first().getResourceType());
+ }
}
}
@@ -139,4 +147,6 @@
}
}
+ protected void cycleDone() {
+ }
}
\ No newline at end of file
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResource.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResource.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResource.java Mon Aug 17 19:36:18 2009
@@ -18,297 +18,45 @@
*/
package org.apache.sling.osgi.installer.impl;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
import java.util.Map;
-import java.util.Properties;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-
-import org.apache.sling.osgi.installer.InstallableResource;
-import org.apache.sling.osgi.installer.impl.propertyconverter.PropertyConverter;
-import org.apache.sling.osgi.installer.impl.propertyconverter.PropertyValue;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
/** A resource that's been registered in the OSGi controller.
* Data can be either an InputStream or a Dictionary, and we store
* it locally to avoid holding up to classes or data from our
* clients, in case those disappear while we're installing stuff.
*/
-public class RegisteredResource {
- private final String url;
- private final String digest;
- private final File dataFile;
- private final String entity;
- private final Dictionary<String, Object> dictionary;
- private final Manifest manifest;
- private static long fileNumber;
-
- static enum State {
- NEW,
- ACTIVE,
- INSTALLED,
- IGNORED,
- REMOVED,
- }
- private State desiredState = State.ACTIVE;
- private State actualState = State.NEW;
-
- static enum ResourceType {
+public interface RegisteredResource {
+
+ static enum ResourceType {
BUNDLE,
CONFIG
}
- private final ResourceType resourceType;
-
public static final String DIGEST_TYPE = "MD5";
public static final String ENTITY_JAR_PREFIX = "jar:";
public static final String ENTITY_BUNDLE_PREFIX = "bundle:";
public static final String ENTITY_CONFIG_PREFIX = "config:";
- /** Create a RegisteredResource from given data. If the data's extension
- * maps to a configuration and the data provides an input stream, it is
- * converted to a Dictionary
- */
- public RegisteredResource(BundleContext ctx, InstallableResource input) throws IOException {
-
- try {
- url = input.getUrl();
- resourceType = computeResourceType(input.getExtension());
-
- if(resourceType == ResourceType.BUNDLE) {
- if(input.getInputStream() == null) {
- throw new IllegalArgumentException("InputStream is required for BUNDLE resource type: " + input);
- }
- dictionary = null;
- dataFile = getDataFile(ctx);
- copyToLocalStorage(input.getInputStream(), dataFile);
- digest = input.getDigest();
- if(digest == null || digest.length() == 0) {
- throw new IllegalArgumentException(
- "Digest must be supplied for BUNDLE resource type: " + input);
- }
- manifest = getManifest(getInputStream());
- String name = null;
- if(manifest != null) {
- name = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- }
- if(name == null) {
- // not a bundle - use "jar" entity to make it easier to find out
- entity = ENTITY_JAR_PREFIX + input.getUrl();
- } else {
- entity = ENTITY_BUNDLE_PREFIX + name;
- }
- } else {
- dataFile = null;
- manifest = null;
- entity = ENTITY_CONFIG_PREFIX + new ConfigurationPid(input.getUrl()).getCompositePid();
- if(input.getInputStream() == null) {
- // config provided as a Dictionary
- dictionary = copy(input.getDictionary());
- } else {
- dictionary = readDictionary(input.getInputStream());
- }
- try {
- digest = computeDigest(dictionary);
- } catch(NoSuchAlgorithmException nse) {
- throw new IOException("NoSuchAlgorithmException:" + DIGEST_TYPE);
- }
- }
- } finally {
- if(input.getInputStream() != null) {
- input.getInputStream().close();
- }
- }
- }
-
- protected File getDataFile(BundleContext ctx) throws IOException {
- String filename = null;
- synchronized (getClass()) {
- filename = getClass().getSimpleName() + "." + fileNumber++;
- }
- return ctx.getDataFile(filename);
- }
-
- public void cleanup() {
- if(dataFile != null && dataFile.exists()) {
- dataFile.delete();
- }
- }
-
- public String getURL() {
- return url;
- }
-
- public InputStream getInputStream() throws IOException {
- if(dataFile == null) {
- return null;
- }
- return new BufferedInputStream(new FileInputStream(dataFile));
- }
-
- public Dictionary<String, Object> getDictionary() {
- return dictionary;
- }
+ void cleanup();
+ String getURL();
+ InputStream getInputStream() throws IOException;
+ Dictionary<String, Object> getDictionary();
+ String getDigest();
+ String getUrl();
+ boolean isInstallable();
+ void setInstallable(boolean installable);
+ ResourceType getResourceType();
- public String getDigest() {
- return digest;
- }
+ /** Attributes include the bundle symbolic name, bundle version, etc. */
+ Map<String, Object> getAttributes();
- /** Digest is needed to detect changes in data
- * @throws */
- static String computeDigest(Dictionary<String, Object> data) throws IOException, NoSuchAlgorithmException {
- final MessageDigest d = MessageDigest.getInstance(DIGEST_TYPE);
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(data);
- bos.flush();
- d.update(bos.toByteArray());
- return digestToString(d);
- }
-
- /** convert digest to readable string (http://www.javalobby.org/java/forums/t84420.html) */
- private static String digestToString(MessageDigest d) {
- final BigInteger bigInt = new BigInteger(1, d.digest());
- return new String(bigInt.toString(16));
- }
-
- /** Copy data to local storage */
- private void copyToLocalStorage(InputStream data, File f) throws IOException {
- final OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
- try {
- final byte[] buffer = new byte[16384];
- int count = 0;
- while( (count = data.read(buffer, 0, buffer.length)) > 0) {
- os.write(buffer, 0, count);
- }
- os.flush();
- } finally {
- if(os != null) {
- os.close();
- }
- }
- }
-
- /** Convert InputStream to Dictionary using our extended properties format,
- * which supports multi-value properties
- */
- static Dictionary<String, Object> readDictionary(InputStream is) throws IOException {
- final Dictionary<String, Object> result = new Hashtable<String, Object>();
- final PropertyConverter converter = new PropertyConverter();
- final Properties p = new Properties();
- p.load(is);
- for(Map.Entry<Object, Object> e : p.entrySet()) {
- final PropertyValue v = converter.convert((String)e.getKey(), (String)e.getValue());
- result.put(v.getKey(), v.getValue());
- }
- return result;
- }
-
- /** Copy given Dictionary, sorting keys */
- static Dictionary<String, Object> copy(Dictionary<String, Object> d) {
- final Dictionary<String, Object> result = new Hashtable<String, Object>();
- final List<String> keys = new ArrayList<String>();
- final Enumeration<String> e = d.keys();
- while(e.hasMoreElements()) {
- keys.add(e.nextElement());
- }
- Collections.sort(keys);
- for(String key : keys) {
- result.put(key, d.get(key));
- }
- return result;
- }
-
- public String getUrl() {
- return url;
- }
-
- public State getDesiredState() {
- return desiredState;
- }
-
- public void setDesiredState(State desiredState) {
- this.desiredState = desiredState;
- }
-
- public State getActualState() {
- return actualState;
- }
-
- public void setActualState(State actualState) {
- this.actualState = actualState;
- }
-
- public ResourceType getResourceType() {
- return resourceType;
- }
-
- public Manifest getManifest() {
- return manifest;
- }
-
- static ResourceType computeResourceType(String extension) {
- if(extension.equals("jar")) {
- return ResourceType.BUNDLE;
- } else {
- return ResourceType.CONFIG;
- }
- }
-
- /** Return the identifier of the OSGi "entity" that this resource
+ /** Return the identifier of the OSGi "entity" that this resource
* represents, for example "bundle:SID" where SID is the bundle's
* symbolic ID, or "config:PID" where PID is config's PID.
*/
- public String getEntityId() {
- return entity;
- }
+ String getEntityId();
- /** Read the manifest from supplied input stream, which is closed before return */
- static Manifest getManifest(InputStream ins) throws IOException {
- Manifest result = null;
-
- JarInputStream jis = null;
- try {
- jis = new JarInputStream(ins);
- result= jis.getManifest();
-
- } finally {
-
- // close the jar stream or the inputstream, if the jar
- // stream is set, we don't need to close the input stream
- // since closing the jar stream closes the input stream
- if (jis != null) {
- try {
- jis.close();
- } catch (IOException ignore) {
- }
- } else {
- try {
- ins.close();
- } catch (IOException ignore) {
- }
- }
- }
-
- return result;
- }
}
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceComparator.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceComparator.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceComparator.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceComparator.java Mon Aug 17 19:36:18 2009
@@ -20,12 +20,37 @@
import java.util.Comparator;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
/** Comparator that defines priorities between RegisteredResources */
class RegisteredResourceComparator implements Comparator<RegisteredResource >{
public int compare(RegisteredResource a, RegisteredResource b) {
- // TODO
- return 0;
+ if(a.getResourceType() == RegisteredResource.ResourceType.BUNDLE) {
+ return compareBundles(a, b);
+ } else {
+ return compareConfig(a, b);
+ }
+ }
+
+ int compareBundles(RegisteredResource a, RegisteredResource b) {
+
+ final String nameA = (String)a.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);
+ final String nameB = (String)a.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);
+ int result = nameA.compareTo(nameB);
+
+ if(result == 0) {
+ final Version va = (Version)a.getAttributes().get(Constants.BUNDLE_VERSION);
+ final Version vb = (Version)b.getAttributes().get(Constants.BUNDLE_VERSION);
+ // higher version has more priority, must come first so invert comparison
+ result = vb.compareTo(va);
+ }
+
+ return result;
}
+ int compareConfig(RegisteredResource a, RegisteredResource b) {
+ return 0;
+ }
}
Added: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java?rev=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java (added)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,304 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.sling.osgi.installer.InstallableResource;
+import org.apache.sling.osgi.installer.impl.propertyconverter.PropertyConverter;
+import org.apache.sling.osgi.installer.impl.propertyconverter.PropertyValue;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/** A resource that's been registered in the OSGi controller.
+ * Data can be either an InputStream or a Dictionary, and we store
+ * it locally to avoid holding up to classes or data from our
+ * clients, in case those disappear while we're installing stuff.
+ */
+public class RegisteredResourceImpl implements RegisteredResource {
+ private final String url;
+ private final String digest;
+ private final File dataFile;
+ private final String entity;
+ private final Dictionary<String, Object> dictionary;
+ private final Map<String, Object> attributes = new HashMap<String, Object>();
+ private static long fileNumber;
+ private boolean installable = true;
+
+ static enum ResourceType {
+ BUNDLE,
+ CONFIG
+ }
+
+ private final RegisteredResource.ResourceType resourceType;
+
+ public static final String DIGEST_TYPE = "MD5";
+ public static final String ENTITY_JAR_PREFIX = "jar:";
+ public static final String ENTITY_BUNDLE_PREFIX = "bundle:";
+ public static final String ENTITY_CONFIG_PREFIX = "config:";
+
+ /** Create a RegisteredResource from given data. If the data's extension
+ * maps to a configuration and the data provides an input stream, it is
+ * converted to a Dictionary
+ */
+ public RegisteredResourceImpl(BundleContext ctx, InstallableResource input) throws IOException {
+
+ try {
+ url = input.getUrl();
+ resourceType = computeResourceType(input.getExtension());
+
+ if(resourceType == RegisteredResource.ResourceType.BUNDLE) {
+ if(input.getInputStream() == null) {
+ throw new IllegalArgumentException("InputStream is required for BUNDLE resource type: " + input);
+ }
+ dictionary = null;
+ dataFile = getDataFile(ctx);
+ copyToLocalStorage(input.getInputStream(), dataFile);
+ digest = input.getDigest();
+ if(digest == null || digest.length() == 0) {
+ throw new IllegalArgumentException(
+ "Digest must be supplied for BUNDLE resource type: " + input);
+ }
+ setAttributesFromManifest();
+ final String name = (String)attributes.get(Constants.BUNDLE_SYMBOLICNAME);
+ if(name == null) {
+ // not a bundle - use "jar" entity to make it easier to find out
+ entity = ENTITY_JAR_PREFIX + input.getUrl();
+ } else {
+ entity = ENTITY_BUNDLE_PREFIX + name;
+ }
+ } else {
+ dataFile = null;
+ entity = ENTITY_CONFIG_PREFIX + new ConfigurationPid(input.getUrl()).getCompositePid();
+ if(input.getInputStream() == null) {
+ // config provided as a Dictionary
+ dictionary = copy(input.getDictionary());
+ } else {
+ dictionary = readDictionary(input.getInputStream());
+ }
+ try {
+ digest = computeDigest(dictionary);
+ } catch(NoSuchAlgorithmException nse) {
+ throw new IOException("NoSuchAlgorithmException:" + DIGEST_TYPE);
+ }
+ }
+ } finally {
+ if(input.getInputStream() != null) {
+ input.getInputStream().close();
+ }
+ }
+ }
+
+ protected File getDataFile(BundleContext ctx) throws IOException {
+ String filename = null;
+ synchronized (getClass()) {
+ filename = getClass().getSimpleName() + "." + fileNumber++;
+ }
+ return ctx.getDataFile(filename);
+ }
+
+ public void cleanup() {
+ if(dataFile != null && dataFile.exists()) {
+ dataFile.delete();
+ }
+ }
+
+ public String getURL() {
+ return url;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ if(dataFile == null) {
+ return null;
+ }
+ return new BufferedInputStream(new FileInputStream(dataFile));
+ }
+
+ public Dictionary<String, Object> getDictionary() {
+ return dictionary;
+ }
+
+ public String getDigest() {
+ return digest;
+ }
+
+ /** Digest is needed to detect changes in data
+ * @throws */
+ static String computeDigest(Dictionary<String, Object> data) throws IOException, NoSuchAlgorithmException {
+ final MessageDigest d = MessageDigest.getInstance(DIGEST_TYPE);
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(data);
+ bos.flush();
+ d.update(bos.toByteArray());
+ return digestToString(d);
+ }
+
+ /** convert digest to readable string (http://www.javalobby.org/java/forums/t84420.html) */
+ private static String digestToString(MessageDigest d) {
+ final BigInteger bigInt = new BigInteger(1, d.digest());
+ return new String(bigInt.toString(16));
+ }
+
+ /** Copy data to local storage */
+ private void copyToLocalStorage(InputStream data, File f) throws IOException {
+ final OutputStream os = new BufferedOutputStream(new FileOutputStream(f));
+ try {
+ final byte[] buffer = new byte[16384];
+ int count = 0;
+ while( (count = data.read(buffer, 0, buffer.length)) > 0) {
+ os.write(buffer, 0, count);
+ }
+ os.flush();
+ } finally {
+ if(os != null) {
+ os.close();
+ }
+ }
+ }
+
+ /** Convert InputStream to Dictionary using our extended properties format,
+ * which supports multi-value properties
+ */
+ static Dictionary<String, Object> readDictionary(InputStream is) throws IOException {
+ final Dictionary<String, Object> result = new Hashtable<String, Object>();
+ final PropertyConverter converter = new PropertyConverter();
+ final Properties p = new Properties();
+ p.load(is);
+ for(Map.Entry<Object, Object> e : p.entrySet()) {
+ final PropertyValue v = converter.convert((String)e.getKey(), (String)e.getValue());
+ result.put(v.getKey(), v.getValue());
+ }
+ return result;
+ }
+
+ /** Copy given Dictionary, sorting keys */
+ static Dictionary<String, Object> copy(Dictionary<String, Object> d) {
+ final Dictionary<String, Object> result = new Hashtable<String, Object>();
+ final List<String> keys = new ArrayList<String>();
+ final Enumeration<String> e = d.keys();
+ while(e.hasMoreElements()) {
+ keys.add(e.nextElement());
+ }
+ Collections.sort(keys);
+ for(String key : keys) {
+ result.put(key, d.get(key));
+ }
+ return result;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public RegisteredResource.ResourceType getResourceType() {
+ return resourceType;
+ }
+
+ static RegisteredResource.ResourceType computeResourceType(String extension) {
+ if(extension.equals("jar")) {
+ return RegisteredResource.ResourceType.BUNDLE;
+ } else {
+ return RegisteredResource.ResourceType.CONFIG;
+ }
+ }
+
+ /** Return the identifier of the OSGi "entity" that this resource
+ * represents, for example "bundle:SID" where SID is the bundle's
+ * symbolic ID, or "config:PID" where PID is config's PID.
+ */
+ public String getEntityId() {
+ return entity;
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attributes;
+ }
+
+ public boolean isInstallable() {
+ return installable;
+ }
+
+ public void setInstallable(boolean installable) {
+ this.installable = installable;
+ }
+
+ /** Read the manifest from supplied input stream, which is closed before return */
+ static Manifest getManifest(InputStream ins) throws IOException {
+ Manifest result = null;
+
+ JarInputStream jis = null;
+ try {
+ jis = new JarInputStream(ins);
+ result= jis.getManifest();
+
+ } finally {
+
+ // close the jar stream or the inputstream, if the jar
+ // stream is set, we don't need to close the input stream
+ // since closing the jar stream closes the input stream
+ if (jis != null) {
+ try {
+ jis.close();
+ } catch (IOException ignore) {
+ }
+ } else {
+ try {
+ ins.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void setAttributesFromManifest() throws IOException {
+ final Manifest m = getManifest(getInputStream());
+ if(m != null) {
+ attributes.put(Constants.BUNDLE_SYMBOLICNAME, m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME));
+ attributes.put(Constants.BUNDLE_VERSION,
+ new Version(m.getMainAttributes().getValue(Constants.BUNDLE_VERSION)));
+ }
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallRemoveTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallRemoveTask.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallRemoveTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallRemoveTask.java Mon Aug 17 19:36:18 2009
@@ -50,7 +50,7 @@
if(isInstallOrUpdate()) {
return TaskOrder.BUNDLE_INSTALL_ORDER + uri;
} else {
- return TaskOrder.BUNDLE_UNINSTALL_ORDER + uri;
+ return TaskOrder.BUNDLE_REMOVE_ORDER + uri;
}
}
@@ -87,17 +87,10 @@
throw new IOException("RegisteredResource does not adapt to an InputStream: " + uri);
}
- final Manifest m = data.getManifest();
- if(m == null) {
- throw new IOException("Manifest not found for RegisteredResource " + uri);
- }
-
// Update if we already have a bundle id, else install
- Bundle b;
- boolean updated = false;
+ Bundle b = null;
try {
b = null;
- updated = false;
// check whether we know the bundle and it exists
final Long longId = (Long) attributes.get(Storage.KEY_BUNDLE_ID);
@@ -108,7 +101,7 @@
// 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) {
- b = TaskUtilities.getMatchingBundle(bundleContext, m);
+ b = TaskUtilities.getMatchingBundle(bundleContext, (String)data.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME));
}
// If the bundle (or one with the same symbolic name) is
@@ -116,7 +109,7 @@
// version
if (b != null) {
final Version installedVersion = new Version((String)(b.getHeaders().get(Constants.BUNDLE_VERSION)));
- final Version newBundleVersion = new Version(m.getMainAttributes().getValue(Constants.BUNDLE_VERSION));
+ final Version newBundleVersion = (Version)(data.getAttributes().get(Constants.BUNDLE_VERSION));
if(ignoreNewBundle(b.getSymbolicName(), uri, installedVersion, newBundleVersion)) {
return false;
}
@@ -130,7 +123,6 @@
}
b.stop();
b.update(is);
- updated = true;
tctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask());
tctx.addTaskToCurrentCycle(new BundleStartTask(b.getBundleId()));
} else {
Added: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java?rev=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java (added)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,57 @@
+/*
+ * 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.tasks;
+
+import org.apache.sling.osgi.installer.OsgiInstaller;
+import org.apache.sling.osgi.installer.impl.OsgiInstallerContext;
+import org.apache.sling.osgi.installer.impl.OsgiInstallerTask;
+import org.apache.sling.osgi.installer.impl.RegisteredResource;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+/** Remove a bundle from a RegisteredResource. Creates
+ * a refresh packages task when executed.
+ */
+public class BundleRemoveTask extends OsgiInstallerTask {
+
+ private final RegisteredResource resource;
+
+ public BundleRemoveTask(RegisteredResource r) {
+ this.resource = r;
+ }
+
+ @Override
+ public void execute(OsgiInstallerContext ctx) throws Exception {
+ final String symbolicName = (String)resource.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);
+ final Bundle b = TaskUtilities.getMatchingBundle(ctx.getBundleContext(), symbolicName);
+ if(b == null) {
+ throw new IllegalStateException("Bundle to remove (" + symbolicName + ") not found");
+ }
+ b.stop();
+ b.uninstall();
+ ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask());
+ ctx.incrementCounter(OsgiInstaller.OSGI_TASKS_COUNTER);
+ }
+
+ @Override
+ public String getSortKey() {
+ return TaskOrder.BUNDLE_REMOVE_ORDER;
+ }
+
+}
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: 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=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java (added)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,64 @@
+/*
+ * 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.tasks;
+
+import org.apache.sling.osgi.installer.OsgiInstaller;
+import org.apache.sling.osgi.installer.impl.OsgiInstallerContext;
+import org.apache.sling.osgi.installer.impl.OsgiInstallerTask;
+import org.apache.sling.osgi.installer.impl.RegisteredResource;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+/** Update a bundle from a RegisteredResource. Creates
+ * a bundleStartTask to restart the bundle if it was
+ * active before the update.
+ */
+public class BundleUpdateTask extends OsgiInstallerTask {
+
+ private final RegisteredResource resource;
+
+ public BundleUpdateTask(RegisteredResource r) {
+ this.resource = r;
+ }
+
+ public RegisteredResource getResource() {
+ return resource;
+ }
+
+ @Override
+ public void execute(OsgiInstallerContext ctx) throws Exception {
+ final String symbolicName = (String)resource.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME);
+ final Bundle b = TaskUtilities.getMatchingBundle(ctx.getBundleContext(), symbolicName);
+ if(b == null) {
+ throw new IllegalStateException("Bundle to update (" + symbolicName + ") not found");
+ }
+ if(b.getState() == Bundle.ACTIVE) {
+ ctx.addTaskToCurrentCycle(new BundleStartTask(b.getBundleId()));
+ }
+ b.stop();
+ b.update(resource.getInputStream());
+ ctx.incrementCounter(OsgiInstaller.OSGI_TASKS_COUNTER);
+ }
+
+ @Override
+ public String getSortKey() {
+ return TaskOrder.BUNDLE_UPDATE_ORDER;
+ }
+
+}
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskOrder.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskOrder.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskOrder.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskOrder.java Mon Aug 17 19:36:18 2009
@@ -22,8 +22,9 @@
class TaskOrder {
static final String CONFIG_UNINSTALL_ORDER = "10-";
static final String CONFIG_INSTALL_ORDER = "20-";
- static final String BUNDLE_UNINSTALL_ORDER = "30-";
- static final String BUNDLE_INSTALL_ORDER = "40-";
- static final String REFRESH_PACKAGES_ORDER = "50-";
- static final String BUNDLE_START_ORDER = "60-";
+ static final String BUNDLE_REMOVE_ORDER = "30-";
+ static final String BUNDLE_UPDATE_ORDER = "40-";
+ static final String BUNDLE_INSTALL_ORDER = "50-";
+ static final String REFRESH_PACKAGES_ORDER = "60-";
+ static final String BUNDLE_START_ORDER = "70-";
}
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskUtilities.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskUtilities.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskUtilities.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/TaskUtilities.java Mon Aug 17 19:36:18 2009
@@ -1,22 +1,17 @@
package org.apache.sling.osgi.installer.impl.tasks;
import java.io.IOException;
-import java.io.InputStream;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
import org.apache.sling.osgi.installer.impl.ConfigurationPid;
import org.apache.sling.osgi.installer.impl.OsgiInstallerContext;
-import org.apache.sling.osgi.installer.impl.RegisteredResource;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
/** Misc.utilities for classes of this package */
-class TaskUtilities {
+public class TaskUtilities {
/**
* Returns a bundle with the same symbolic name as the bundle provided in
* the installable data. If the installable data has no manifest file or the
@@ -36,14 +31,13 @@
* with a symbolic name.
* @throws IOException If an error occurrs reading from the input stream.
*/
- static Bundle getMatchingBundle(BundleContext ctx, Manifest m) throws IOException {
+ public static Bundle getMatchingBundle(BundleContext ctx, String bundleSymbolicName) {
- final String symbolicName = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
- if (symbolicName != null) {
+ if (bundleSymbolicName != null) {
Bundle[] bundles = ctx.getBundles();
for (Bundle bundle : bundles) {
- if (symbolicName.equals(bundle.getSymbolicName())) {
+ if (bundleSymbolicName.equals(bundle.getSymbolicName())) {
return bundle;
}
}
@@ -53,7 +47,7 @@
}
/** Get or create configuration */
- static Configuration getConfiguration(ConfigurationPid cp, boolean createIfNeeded, OsgiInstallerContext ocs)
+ public static Configuration getConfiguration(ConfigurationPid cp, boolean createIfNeeded, OsgiInstallerContext ocs)
throws IOException, InvalidSyntaxException
{
final ConfigurationAdmin configurationAdmin = ocs.getConfigurationAdmin();
Added: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java?rev=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java (added)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,199 @@
+/*
+ * 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.assertTrue;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.sling.osgi.installer.impl.tasks.BundleInstallTask;
+import org.apache.sling.osgi.installer.impl.tasks.BundleRemoveTask;
+import org.apache.sling.osgi.installer.impl.tasks.BundleUpdateTask;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+public class BundleTaskCreatorTest {
+ public static final String SN = "TestSymbolicName";
+
+ private SortedSet<OsgiInstallerTask> getTasks(RegisteredResource [] resources, BundleTaskCreator btc) {
+ final SortedSet<RegisteredResource> s = OsgiInstallerThread.createRegisteredResourcesEntry();
+ for(RegisteredResource r : resources) {
+ s.add(r);
+ }
+
+ final SortedSet<OsgiInstallerTask> tasks = new TreeSet<OsgiInstallerTask>();
+ btc.createTasks(null, s, tasks);
+ return tasks;
+ }
+
+ @Test
+ public void testSingleBundleNew() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0")
+ };
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleInstallTask", s.first() instanceof BundleInstallTask);
+ }
+
+ @Test
+ public void testSingleBundleAlreadyInstalled() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0")
+ };
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected no tasks, same version is active", 0, s.size());
+ }
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.RESOLVED);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected no tasks, same version is installed", 0, s.size());
+ }
+ }
+
+ @Test
+ public void testBundleUpgrade() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.1")
+ };
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleUpdateTask", s.first() instanceof BundleUpdateTask);
+ }
+ }
+
+ @Test
+ public void testBundleUpgradeBothRegistered() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.1"),
+ new MockBundleResource(SN, "1.0")
+ };
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleUpdateTask", s.first() instanceof BundleUpdateTask);
+ }
+ }
+
+ @Test
+ public void testBundleUpgradeBothRegisteredReversed() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0"),
+ new MockBundleResource(SN, "1.1")
+ };
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleUpdateTask", s.first() instanceof BundleUpdateTask);
+ }
+ }
+
+ @Test
+ public void testBundleUpgradeSnapshot() {
+ final String v = "2.0.7.-SNAPSHOT";
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, v)
+ };
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, v, Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleUpdateTask", s.first() instanceof BundleUpdateTask);
+ }
+ }
+
+ @Test
+ public void testBundleRemoveSingle() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0")
+ };
+ r[0].setInstallable(false);
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.0", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleRemoveTask", s.first() instanceof BundleRemoveTask);
+ }
+ }
+
+ @Test
+ public void testBundleRemoveMultiple() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0"),
+ new MockBundleResource(SN, "1.1"),
+ new MockBundleResource(SN, "2.0")
+ };
+ for(RegisteredResource x : r) {
+ x.setInstallable(false);
+ }
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.1", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleRemoveTask", s.first() instanceof BundleRemoveTask);
+ }
+ }
+
+ @Test
+ public void testDowngradeOfRemovedResource() {
+ final RegisteredResource [] r = {
+ new MockBundleResource(SN, "1.0"),
+ new MockBundleResource(SN, "1.1"),
+ };
+
+ // Simulate V1.1 installed but resource is gone -> downgrade to 1.0
+ r[1].setInstallable(false);
+
+ {
+ final MockBundleTaskCreator c = new MockBundleTaskCreator();
+ c.addBundleInfo(SN, "1.1", Bundle.ACTIVE);
+ final SortedSet<OsgiInstallerTask> s = getTasks(r, c);
+ assertEquals("Expected one task", 1, s.size());
+ assertTrue("Expected a BundleUpdateTask", s.first() instanceof BundleUpdateTask);
+ final BundleUpdateTask t = (BundleUpdateTask)s.first();
+ assertEquals("Update should be to V1.0", r[0], t.getResource());
+ }
+ }
+
+}
\ No newline at end of file
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/BundleTaskCreatorTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryConversionTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryConversionTest.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryConversionTest.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryConversionTest.java Mon Aug 17 19:36:18 2009
@@ -74,7 +74,7 @@
;
final ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes());
- final Dictionary<?, ?> d = RegisteredResource.readDictionary(is);
+ final Dictionary<?, ?> d = RegisteredResourceImpl.readDictionary(is);
is.close();
assertEquals("Number of entries must match", 4, d.size());
@@ -96,7 +96,7 @@
;
final ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes());
- final Dictionary<?, ?> d = RegisteredResource.readDictionary(is);
+ final Dictionary<?, ?> d = RegisteredResourceImpl.readDictionary(is);
is.close();
assertEquals("Number of entries must match", 5, d.size());
Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryDigestTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryDigestTest.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryDigestTest.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/DictionaryDigestTest.java Mon Aug 17 19:36:18 2009
@@ -33,7 +33,7 @@
private String testDigestChanged(Dictionary<String, Object> d,
String oldDigest, int step, boolean shouldChange) throws Exception {
- final String newDigest = RegisteredResource.computeDigest(d);
+ final String newDigest = RegisteredResourceImpl.computeDigest(d);
if(shouldChange) {
assertTrue("Digest (" + newDigest + ") should have changed at step " + step, !newDigest.equals(oldDigest));
} else {
@@ -51,8 +51,8 @@
assertEquals(
"Two dictionary with same values have the same key",
- RegisteredResource.computeDigest(d1),
- RegisteredResource.computeDigest(d2)
+ RegisteredResourceImpl.computeDigest(d1),
+ RegisteredResourceImpl.computeDigest(d2)
);
}
Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/LocalFileRegisteredResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/LocalFileRegisteredResource.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/LocalFileRegisteredResource.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/LocalFileRegisteredResource.java Mon Aug 17 19:36:18 2009
@@ -25,7 +25,7 @@
import org.osgi.framework.BundleContext;
/** RegisteredResource that stores data to a local temporary file */
-class LocalFileRegisteredResource extends RegisteredResource {
+class LocalFileRegisteredResource extends RegisteredResourceImpl {
private File storage;
LocalFileRegisteredResource(InstallableResource r) throws IOException {
Added: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java?rev=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java (added)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,83 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/** Mock RegisteredResource that simulates a bundle */
+public class MockBundleResource implements RegisteredResource {
+
+ private final Map<String, Object> attributes = new HashMap<String, Object>();
+ private boolean installable = true;
+
+ MockBundleResource(String symbolicName, String version) {
+ attributes.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+ attributes.put(Constants.BUNDLE_VERSION, new Version(version));
+ }
+
+ public void cleanup() {
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attributes;
+ }
+
+ public Dictionary<String, Object> getDictionary() {
+ return null;
+ }
+
+ public String getDigest() {
+ return null;
+ }
+
+ public String getEntityId() {
+ return null;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return null;
+ }
+
+ public ResourceType getResourceType() {
+ return RegisteredResource.ResourceType.BUNDLE;
+ }
+
+ public String getUrl() {
+ return null;
+ }
+
+ public String getURL() {
+ return null;
+ }
+
+ public boolean isInstallable() {
+ return installable;
+ }
+
+ public void setInstallable(boolean installable) {
+ this.installable = installable;
+ }
+}
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleResource.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java?rev=805111&view=auto
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java (added)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java Mon Aug 17 19:36:18 2009
@@ -0,0 +1,42 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/** BundleTaskCreator that simulates the presence and state of bundles */
+class MockBundleTaskCreator extends BundleTaskCreator {
+
+ private final Map<String, BundleInfo> fakeBundleInfo = new HashMap<String, BundleInfo>();
+
+ void addBundleInfo(String symbolicName, String version, int state) {
+ fakeBundleInfo.put(symbolicName, new BundleInfo(new Version(version), state));
+ }
+
+ @Override
+ protected BundleInfo getBundleInfo(BundleContext ctx, RegisteredResource bundle) {
+ return fakeBundleInfo.get(bundle.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME));
+ }
+
+}
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/MockBundleTaskCreator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java Mon Aug 17 19:36:18 2009
@@ -34,6 +34,7 @@
import java.util.Hashtable;
import org.apache.sling.osgi.installer.InstallableResource;
+import org.osgi.framework.Constants;
public class RegisteredResourceTest {
@@ -144,8 +145,8 @@
d2.put(keys[i], keys[i] + "." + keys[i]);
}
- final RegisteredResource r1 = new RegisteredResource(null, new InstallableResource("url1", d1));
- final RegisteredResource r2 = new RegisteredResource(null, new InstallableResource("url1", d2));
+ final RegisteredResource r1 = new RegisteredResourceImpl(null, new InstallableResource("url1", d1));
+ final RegisteredResource r2 = new RegisteredResourceImpl(null, new InstallableResource("url1", d2));
assertEquals(
"Two RegisteredResource (Dictionary) with same values but different key orderings must have the same key",
@@ -161,8 +162,8 @@
final ByteArrayInputStream s1 = new ByteArrayInputStream(d1.getBytes());
final ByteArrayInputStream s2 = new ByteArrayInputStream(d2.getBytes());
- final RegisteredResource r1 = new RegisteredResource(null, new InstallableResource("url1.properties", s1, null));
- final RegisteredResource r2 = new RegisteredResource(null, new InstallableResource("url2.properties", s2, null));
+ final RegisteredResource r1 = new RegisteredResourceImpl(null, new InstallableResource("url1.properties", s1, null));
+ final RegisteredResource r2 = new RegisteredResourceImpl(null, new InstallableResource("url2.properties", s2, null));
assertEquals(
"Two RegisteredResource (InputStream) with same values but different key orderings must have the same key",
@@ -175,14 +176,14 @@
final File f = getTestBundle("testbundle-1.0.jar");
final InstallableResource i = new InstallableResource(f.getAbsolutePath(), new FileInputStream(f), f.getName());
final RegisteredResource r = new LocalFileRegisteredResource(i);
- assertNotNull("RegisteredResource must have manifest", r.getManifest());
+ assertNotNull("RegisteredResource must have bundle symbolic name", r.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME));
assertEquals("RegisteredResource entity ID must match", "bundle:osgi-installer-testbundle", r.getEntityId());
}
@org.junit.Test public void testConfigEntity() throws Exception {
final InstallableResource i = new InstallableResource("/foo/someconfig", new Hashtable<String, Object>());
final RegisteredResource r = new LocalFileRegisteredResource(i);
- assertNull("RegisteredResource must not have manifest", r.getManifest());
+ assertNull("RegisteredResource must not have bundle symbolic name", r.getAttributes().get(Constants.BUNDLE_SYMBOLICNAME));
assertEquals("RegisteredResource entity ID must match", "config:someconfig", r.getEntityId());
}
}
\ No newline at end of file
Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/TaskOrderingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/TaskOrderingTest.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/TaskOrderingTest.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/TaskOrderingTest.java Mon Aug 17 19:36:18 2009
@@ -35,6 +35,7 @@
/** Test the ordering and duplicates elimination of
* OsgiControllerTasks
*/
+// TODO add bundleUpdateTask and others
public class TaskOrderingTest {
private Set<OsgiInstallerTask> taskSet;
@@ -46,7 +47,7 @@
}
private static RegisteredResource getRegisteredResource(String url) throws IOException {
- return new RegisteredResource(null, new InstallableResource(url, new Hashtable<String, Object>()));
+ return new RegisteredResourceImpl(null, new InstallableResource(url, new Hashtable<String, Object>()));
}
private void assertOrder(int testId, Collection<OsgiInstallerTask> actual, OsgiInstallerTask [] expected) {
Modified: sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallTest.java?rev=805111&r1=805110&r2=805111&view=diff
==============================================================================
--- sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallTest.java (original)
+++ sling/trunk/installer/osgi/it/src/test/java/org/apache/sling/osgi/installer/it/BundleInstallTest.java Mon Aug 17 19:36:18 2009
@@ -71,14 +71,13 @@
assertEquals("Version must be 1.1", "1.1", b.getHeaders().get(BUNDLE_VERSION));
}
- /** TODO
// Upgrade to later version, verify
{
resetCounters();
installer.addResource(getInstallableResource(
getTestBundle("org.apache.sling.osgi.installer.it-" + POM_VERSION + "-testbundle-1.2.jar")));
// wait for two tasks: update (includes stop) and start
- waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 1);
+ waitForInstallerAction(OsgiInstaller.OSGI_TASKS_COUNTER, 2);
final Bundle b = findBundle(symbolicName);
assertNotNull("Test bundle 1.2 must be found after waitForInstallerAction", b);
assertEquals("Installed bundle must be started", Bundle.ACTIVE, b.getState());
@@ -87,16 +86,21 @@
}
// Downgrade to lower version, installed bundle must not change
- {
- c.scheduleInstallOrUpdate(uri, new FileInstallableResource(getTestBundle("org.apache.sling.osgi.installer.it-" + POM_VERSION + "-testbundle-1.0.jar")));
- c.waitForInstallerAction();
- final Bundle b = findBundle(symbolicName);
- assertNotNull("Test bundle 1.2 must be found after waitForInstallerAction", b);
- assertEquals("Installed bundle must be started", Bundle.ACTIVE, b.getState());
- assertEquals("Version must be 1.2 after ignored downgrade", "1.2", b.getHeaders().get(BUNDLE_VERSION));
- assertEquals("Bundle ID must not change after downgrade", bundleId, b.getBundleId());
- }
+ {
+ resetCounters();
+ installer.addResource(getInstallableResource(
+ getTestBundle("org.apache.sling.osgi.installer.it-" + POM_VERSION + "-testbundle-1.0.jar")));
+
+ // wait for two cycles to make sure no updates happen
+ waitForInstallerAction(OsgiInstaller.INSTALLER_CYCLES_COUNTER, 2);
+ final Bundle b = findBundle(symbolicName);
+ assertNotNull("Test bundle 1.2 must still be found after waitForInstallerAction", b);
+ assertEquals("Installed bundle must be started", Bundle.ACTIVE, b.getState());
+ assertEquals("Version must be 1.2 after ignored downgrade", "1.2", b.getHeaders().get(BUNDLE_VERSION));
+ assertEquals("Bundle ID must not change after ignored downgrade", bundleId, b.getBundleId());
+ }
+ /** TODO
// Uninstall
{
c.scheduleUninstall(uri);