You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/12/02 14:48:49 UTC
svn commit: r722457 - in /incubator/sling/trunk/extensions/jcrinstall/src:
main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/
main/java/org/apache/sling/jcr/jcrinstall/osgi/
main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/
main/resources/OSGI-INF/...
Author: bdelacretaz
Date: Tue Dec 2 05:48:48 2008
New Revision: 722457
URL: http://svn.apache.org/viewvc?rev=722457&view=rev
Log:
SLING-747 - Use OSGi start levels in jcrinstall, to better control bundles start/stop - work in progress, manual tests ok
Added:
incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/
incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/
incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties (with props)
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java (with props)
Removed:
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java
Modified:
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ConfigInstallableData.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileInstallableData.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileNodeConverter.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/InstallableData.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiResourceProcessor.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/MockInstallableData.java
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ConfigInstallableData.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ConfigInstallableData.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ConfigInstallableData.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ConfigInstallableData.java Tue Dec 2 05:48:48 2008
@@ -67,4 +67,9 @@
final BigInteger bigInt = new BigInteger(1, d.digest());
return new String(bigInt.toString(16));
}
+
+ /** Not applicable for config nodes, return 0 */
+ public int getBundleStartLevel() {
+ return 0;
+ }
}
\ No newline at end of file
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileInstallableData.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileInstallableData.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileInstallableData.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileInstallableData.java Tue Dec 2 05:48:48 2008
@@ -41,14 +41,16 @@
private final Property dataProperty;
private final String digest;
private final String path;
+ private final int bundleStartLevel;
@Override
public String toString() {
return getClass().getSimpleName() + ": " + path;
}
- FileInstallableData(Node n) throws RepositoryException {
+ FileInstallableData(Node n, int bundleStartLevel) throws RepositoryException {
this.path = n.getPath();
+ this.bundleStartLevel = bundleStartLevel;
if (n.hasProperty(JCR_CONTENT_LAST_MODIFIED)) {
digest = String.valueOf(n.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate().getTimeInMillis());
} else {
@@ -79,4 +81,8 @@
public String getDigest() {
return digest;
}
+
+ public int getBundleStartLevel() {
+ return bundleStartLevel;
+ }
}
\ No newline at end of file
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileNodeConverter.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileNodeConverter.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileNodeConverter.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileNodeConverter.java Tue Dec 2 05:48:48 2008
@@ -15,12 +15,17 @@
private final RegexpFilter filenameFilter = new RegexpFilter(FILENAME_REGEXP);
private final Logger log = LoggerFactory.getLogger(getClass());
+ private final int bundleStartLevel;
+
+ public FileNodeConverter(int bundleStartLevel) {
+ this.bundleStartLevel = bundleStartLevel;
+ }
public InstallableData convertNode(Node n) throws RepositoryException {
InstallableData result = null;
if(n.hasProperty(FileInstallableData.JCR_CONTENT_DATA) && n.hasProperty(FileInstallableData.JCR_CONTENT_LAST_MODIFIED)) {
if(filenameFilter.accept(n.getName())) {
- result = new FileInstallableData(n);
+ result = new FileInstallableData(n, bundleStartLevel);
} else {
log.debug("Node {} ignored due to {}", n.getPath(), filenameFilter);
}
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java Tue Dec 2 05:48:48 2008
@@ -39,9 +39,10 @@
import org.apache.sling.jcr.jcrinstall.jcr.NodeConverter;
import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
import org.apache.sling.jcr.jcrinstall.osgi.ResourceOverrideRules;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
import org.osgi.service.component.ComponentContext;
+import org.osgi.service.startlevel.StartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,9 +52,10 @@
*
* Calls the OsgiController to install/remove resources.
*
- * @scr.component
- * immediate="true"
- * metatype="no"
+ * @scr.component
+ * label="%jcrinstall.name"
+ * description="%jcrinstall.description"
+ * immediate="true"
* @scr.property
* name="service.description"
* value="Sling jcrinstall OsgiController Service"
@@ -61,28 +63,38 @@
* name="service.vendor"
* value="The Apache Software Foundation"
*/
-public class RepositoryObserver implements Runnable, BundleListener {
+public class RepositoryObserver implements Runnable, FrameworkListener {
- protected SortedSet<WatchedFolder> folders;
+ private final SortedSet<WatchedFolder> folders = new TreeSet<WatchedFolder>();
private RegexpFilter folderNameFilter;
private RegexpFilter filenameFilter;
private ResourceOverrideRules roRules;
+ private ComponentContext componentContext;
private final PropertiesUtil propertiesUtil = new PropertiesUtil();
- private boolean running;
+ private boolean observationCycleActive;
+ private boolean activated;
/** @scr.reference */
protected OsgiController osgiController;
- /** @scr.reference */
+ /** @scr.reference cardinality="0..1" policy="dynamic" */
protected SlingRepository repository;
+ /** @scr.reference */
+ protected StartLevel startLevel;
+
+ /** @scr.property type="Integer" valueRef="DEFAULT_BUNDLES_START_LEVEL" */
+ private static final String BUNDLES_START_LEVEL__PROPERTY = "bundles.startlevel";
+ private static final int DEFAULT_BUNDLES_START_LEVEL = 30;
+ private int installedBundlesStartLevel = DEFAULT_BUNDLES_START_LEVEL;
+
private Session session;
private File serviceDataFile;
- private long lastBundleEvent;
+ private int startLevelToSetAtStartup;
private final List<NodeConverter> converters = new ArrayList<NodeConverter>();
- private List<WatchedFolderCreationListener> listeners = new LinkedList<WatchedFolderCreationListener>();
+ private final List<WatchedFolderCreationListener> listeners = new LinkedList<WatchedFolderCreationListener>();
/** Default set of root folders to watch */
public static String[] DEFAULT_ROOTS = {"/libs", "/apps"};
@@ -104,12 +116,56 @@
/** Upon activation, find folders to watch under our roots, and observe those
* roots to detect new folders to watch.
*/
- protected void activate(ComponentContext context) throws RepositoryException {
-
- if(context!=null) {
- context.getBundleContext().addBundleListener(this);
+ protected void activate(ComponentContext context) throws Exception {
+ componentContext = context;
+
+ // Context can be null in automated tests, to make them simpler
+ if(context != null) {
+ context.getBundleContext().addFrameworkListener(this);
+ }
+
+ // Read config
+ if(context != null) {
+ final Object prop = context.getProperties().get(BUNDLES_START_LEVEL__PROPERTY);
+ if(prop != null && prop instanceof Number) {
+ installedBundlesStartLevel = ((Number)prop).intValue();
+ log.info("Start level for installed bundles set to {} by {} property", installedBundlesStartLevel, BUNDLES_START_LEVEL__PROPERTY);
+ } else {
+ installedBundlesStartLevel = DEFAULT_BUNDLES_START_LEVEL;
+ log.info("Start level for installed bundles set to default value {}", installedBundlesStartLevel);
+ }
+ }
+
+ // Check start levels
+ if(context != null) {
+ final int myLevel = startLevel.getBundleStartLevel(context.getBundleContext().getBundle());
+ if(installedBundlesStartLevel < myLevel) {
+ // Running at a lower start level than the bundles that we install
+ // allows us to stop them if the repository goes away (SLING-747)
+ log.warn(
+ "The configured start level for bundles installed by jcrinstall ({})"
+ + " should be higher than the jcrinstall start level ({})",
+ installedBundlesStartLevel, myLevel
+ );
+ }
}
- lastBundleEvent = System.currentTimeMillis();
+
+ // Call startup() if we already have a repository, else that will be called
+ // by the bind method
+ if(repository != null) {
+ log.debug("activate()");
+ startup();
+ } else {
+ log.debug("activate() - Repository not available, cannot install bundles yet");
+ }
+
+ activated = true;
+ }
+
+ /** Called at activation time, or when repository becomes available again
+ * after going away. */
+ protected void startup() throws Exception {
+ log.debug("startup()");
// TODO make this more configurable (in sync with ResourceOverrideRulesImpl)
final String [] roots = DEFAULT_ROOTS;
@@ -123,10 +179,10 @@
* Using services and a whiteboard pattern for these would be nice,
* but that could be problematic at startup due to async loading
*/
- converters.add(new FileNodeConverter());
+ converters.add(new FileNodeConverter(installedBundlesStartLevel));
converters.add(new ConfigNodeConverter());
- String folderNameRegexp = getPropertyValue(context, FOLDER_NAME_REGEXP_PROPERTY);
+ String folderNameRegexp = getPropertyValue(componentContext, FOLDER_NAME_REGEXP_PROPERTY);
if(folderNameRegexp == null) {
folderNameRegexp = DEFAULT_FOLDER_NAME_REGEXP;
log.info("Using default folder name regexp '{}'", DEFAULT_FOLDER_NAME_REGEXP);
@@ -134,7 +190,7 @@
log.info("Using folder name regexp '{}' from context property '{}'", folderNameRegexp, FOLDER_NAME_REGEXP_PROPERTY);
}
folderNameFilter = new RegexpFilter(folderNameRegexp);
- serviceDataFile = getServiceDataFile(context);
+ serviceDataFile = getServiceDataFile(componentContext);
// Listen for any new WatchedFolders created after activation
session = repository.loginAdministrative(repository.getDefaultWorkspace());
@@ -149,13 +205,24 @@
}
// Find folders to watch
- folders = new TreeSet<WatchedFolder>();
for(String root : roots) {
folders.addAll(findWatchedFolders(root));
}
+ // Handle initial uninstalls and installs
+ observationCycleActive = true;
+ final int myStartLevel = startLevel.getStartLevel();
+ handleInitialUninstalls();
+ runOneCycle();
+
+ // Restore start level if we brought it down due to the repository going away
+ if(startLevelToSetAtStartup > 0 && startLevelToSetAtStartup != myStartLevel) {
+ log.info("startup(): resetting start level to {}", startLevelToSetAtStartup);
+ startLevel.setStartLevel(startLevelToSetAtStartup);
+ startLevelToSetAtStartup = 0;
+ }
+
// start queue processing
- running = true;
final Thread t = new Thread(this, getClass().getSimpleName() + "_" + System.currentTimeMillis());
t.setDaemon(true);
t.start();
@@ -175,11 +242,22 @@
}
protected void deactivate(ComponentContext context) {
-
- running = false;
+ log.debug("deactivate()");
+ shutdown();
+ if(context != null) {
+ context.getBundleContext().removeFrameworkListener(this);
+ }
+ activated = false;
+ componentContext = null;
+ startLevelToSetAtStartup = 0;
+ }
+
+ /** Called at deactivation time, or when repository stops being available */
+ protected void shutdown() {
+ log.debug("shutdown()");
+
+ observationCycleActive = false;
- context.getBundleContext().removeBundleListener(this);
-
for(WatchedFolder f : folders) {
f.cleanup();
}
@@ -199,6 +277,15 @@
listeners.clear();
folders.clear();
+
+ if(componentContext != null) {
+ final int currentStartLevel = startLevel.getStartLevel();
+ final int myStartLevel = startLevel.getBundleStartLevel(componentContext.getBundleContext().getBundle());
+ if(currentStartLevel > myStartLevel) {
+ log.info("shutdown(): changing start level from {} to the jcrinstall start level of {}", currentStartLevel, myStartLevel);
+ startLevel.setStartLevel(myStartLevel);
+ }
+ }
}
/** Add WatchedFolders that have been discovered by our WatchedFolderCreationListeners, if any */
@@ -315,34 +402,28 @@
public void run() {
log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
- // Wait some time after receiving our last bundle event, to
- // avoid uninstalling stuff while components might be starting
- final long bundleEventDelayMsec = 1000;
- boolean logged = false;
- while(System.currentTimeMillis() - lastBundleEvent < bundleEventDelayMsec) {
- if(!logged) {
- log.info("Bundle events were detected in the last {} msec, waiting...", bundleEventDelayMsec);
- }
- logged = true;
-
- try {
- Thread.sleep(100);
- } catch(InterruptedException ignore) {
- // ignore
- }
- }
- log.info("No bundle events in the last {} msec, starting processing", bundleEventDelayMsec);
-
-
// We could use the scheduler service but that makes things harder to test
- boolean firstCycle = true;
- while (running) {
+ boolean scanning = false;
+ boolean oldScanning = !scanning;
+
+ while (observationCycleActive) {
try {
- if(firstCycle) {
- handleInitialUninstalls();
- firstCycle = false;
- }
- runOneCycle();
+ final int currentLevel = startLevel.getStartLevel();
+ scanning = currentLevel >= installedBundlesStartLevel;
+ if(scanning != oldScanning) {
+ if(scanning) {
+ log.info("Scanning enabled, current start level ({}) equals or above {} (start level of installed bundles)",
+ currentLevel, installedBundlesStartLevel);
+ } else {
+ log.info("Scanning disabled, current start level ({}) is below {} (start level of installed bundles)",
+ currentLevel, installedBundlesStartLevel);
+ }
+ oldScanning = scanning;
+ }
+
+ if(scanning) {
+ runOneCycle();
+ }
} catch (IllegalArgumentException ie) {
log.warn("IllegalArgumentException in " + getClass().getSimpleName(), ie);
} catch (RepositoryException re) {
@@ -367,6 +448,9 @@
// Add any new watched folders, and scan those who need it
addNewWatchedFolders();
for(WatchedFolder wf : folders) {
+ if(!observationCycleActive) {
+ break;
+ }
wf.scanIfNeeded(converters);
}
@@ -374,8 +458,43 @@
// resources that we detected
osgiController.executeScheduledOperations();
}
+
+ /** Called when a SlingRepository becomes available, either at activation time
+ * or later, if the repository had disappeared since activated.
+ */
+ protected void bindSlingRepository(SlingRepository r) {
+ repository = r;
+ if(activated) {
+ log.debug("bindSlingRepository()");
+ try {
+ startup();
+ } catch(Exception e) {
+ log.error("Exception in bindSlingRepository/startup", e);
+ }
+ } else {
+ log.debug("bindSlingRepository() but not activated yet, startup() not called");
+ }
+ }
+
+ /** Called when a SlingRepository becomes unavailable, either at deactivation time
+ * or because the repository became unavailable.
+ */
+ protected void unbindSlingRepository(SlingRepository r) {
+ // Store current start level: shutdown() will bring it down and we want
+ // to go back to it if repository comes back
+ startLevelToSetAtStartup = startLevel.getStartLevel();
+ log.debug("unbindSlingRepository() called at start level {}", startLevelToSetAtStartup);
+ shutdown();
+ repository = null;
+ }
+
+ public void frameworkEvent(FrameworkEvent e) {
+ if(e.getType() == FrameworkEvent.STARTLEVEL_CHANGED) {
+ log.info("FrameworkEvent.STARTLEVEL_CHANGED, start level={}", startLevel.getStartLevel());
+ }
+ }
- public void bundleChanged(BundleEvent event) {
- lastBundleEvent = System.currentTimeMillis();
+ protected Set<WatchedFolder> getWatchedFolders() {
+ return folders;
}
}
\ No newline at end of file
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/InstallableData.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/InstallableData.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/InstallableData.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/InstallableData.java Tue Dec 2 05:48:48 2008
@@ -32,4 +32,9 @@
/** Adapt the underlying data to the provided type.
* @return null if cannot be adapted */
<AdapterType> AdapterType adaptTo(Class<AdapterType> type);
+
+ /** If data to install is a Bundle, this is the start level
+ * to use when installing it.
+ */
+ int getBundleStartLevel();
}
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiController.java Tue Dec 2 05:48:48 2008
@@ -34,7 +34,9 @@
*/
int scheduleInstallOrUpdate(String uri, InstallableData data) throws IOException, JcrInstallException;
- /** Schedule uninstallation of resource that was installed via given uri
+ /** Schedule uninstallation of resource that was installed via given uri.
+ * Might be called several times for the same URI - needless calls should
+ * be ignored.
* @param uri Unique identifier for the resource
* @param attributes metadata stored by the OsgiController, will be
* removed after calling this method
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiResourceProcessor.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiResourceProcessor.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/OsgiResourceProcessor.java Tue Dec 2 05:48:48 2008
@@ -38,7 +38,8 @@
*/
int installOrUpdate(String uri, Map<String, Object> attributes, InstallableData data) throws Exception;
- /** Uninstall the resource that was installed via given uri
+ /** Uninstall the resource that was installed via given uri. Calling this with an uri
+ * that is not installed is not an error.
* @param uri Unique identifier for the resource
* @param attributes metadata stored by the OsgiController, will be
* removed after calling this method
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java Tue Dec 2 05:48:48 2008
@@ -22,8 +22,6 @@
import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.INSTALLED;
import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.UPDATED;
-import java.io.BufferedInputStream;
-import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -45,6 +43,7 @@
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.Version;
import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,8 +57,8 @@
public static final String KEY_BUNDLE_ID = "bundle.id";
private final BundleContext ctx;
-
private final PackageAdmin packageAdmin;
+ private final StartLevel startLevel;
/**
* All bundles which were active before {@link #processResourceQueue()}
@@ -89,9 +88,10 @@
private final Logger log = LoggerFactory.getLogger(this.getClass());
- BundleResourceProcessor(BundleContext ctx, PackageAdmin packageAdmin) {
+ BundleResourceProcessor(BundleContext ctx, PackageAdmin packageAdmin, StartLevel startLevel) {
this.ctx = ctx;
this.packageAdmin = packageAdmin;
+ this.startLevel = startLevel;
this.activeBundles = new HashSet<Long>();
this.installedBundles = new ArrayList<Long>();
@@ -175,8 +175,10 @@
needsRefresh = true;
} else {
uri = OsgiControllerImpl.getResourceLocation(uri);
- log.debug("No matching Bundle for uri {}, installing", uri);
+ final int level = installableData.getBundleStartLevel();
+ log.debug("No matching Bundle for uri {}, installing with start level {}", uri, level);
b = ctx.installBundle(uri, data);
+ startLevel.setBundleStartLevel(b, level);
}
} finally {
// data is never null here
@@ -261,7 +263,6 @@
packageAdmin.refreshPackages(null);
} else {
- log.debug("Processing resource queue in START mode");
startBundles();
}
}
@@ -366,8 +367,10 @@
* @param bundleIdCollection The IDs of bundles to be started.
*/
private void startBundles(Collection<Long> bundleIdCollection, String collectionName) {
- log.debug("startBundles({}): {} bundles to process",
- collectionName, bundleIdCollection.size());
+ if(bundleIdCollection.size() > 0) {
+ log.debug("startBundles({}): {} bundles to process",
+ collectionName, bundleIdCollection.size());
+ }
// get the bundle ids and remove them from the collection
Long[] bundleIds;
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java Tue Dec 2 05:48:48 2008
@@ -36,6 +36,7 @@
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,6 +68,9 @@
/** @scr.reference */
private PackageAdmin packageAdmin;
+ /** @scr.reference */
+ protected StartLevel startLevel;
+
/** Storage key: digest of an InstallableData */
public static final String KEY_DIGEST = "data.digest";
@@ -78,7 +82,7 @@
// Note that, in executeScheduledOperations(),
// processors are called in the order of this list
processors = new LinkedList<OsgiResourceProcessor>();
- processors.add(new BundleResourceProcessor(context.getBundleContext(), packageAdmin));
+ processors.add(new BundleResourceProcessor(context.getBundleContext(), packageAdmin, startLevel));
processors.add(new ConfigResourceProcessor(configAdmin));
storage = new Storage(context.getBundleContext().getDataFile(STORAGE_FILENAME));
Added: incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=722457&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties Tue Dec 2 05:48:48 2008
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor generated by the
+# the SCR plugin
+
+jcrinstall.name = jcrinstall
+jcrinstall.description = Installs OSGi bundles and configurations found \
+ in the JCR Repository.
+
+bundles.startlevel.name = Start level of installed bundles
+bundles.startlevel.description = Bundles installed by jcrinstall are set \
+ to this OSGi start level, which should be higher than the start level \
+ of the jcrinstall bundle. The default start level of the framework should \
+ be equal or higher to the configured value, so that installed bundles are \
+ started right after being installed by jcrinstall.
\ No newline at end of file
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java Tue Dec 2 05:48:48 2008
@@ -63,6 +63,7 @@
mockery.checking(new Expectations() {{
allowing(osgiController).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
allowing(osgiController).getInstalledUris(); will(returnValue(installedUri));
+ allowing(osgiController).executeScheduledOperations();
}});
}
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java Tue Dec 2 05:48:48 2008
@@ -21,7 +21,6 @@
import java.io.File;
import java.io.IOException;
import java.util.Properties;
-import java.util.Set;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
@@ -43,19 +42,16 @@
osgiController = c;
scanDelayMsec = 0;
this.serviceDataFile = serviceDataFile;
+ startLevel = new MockStartLevel();
}
public void run() {
// Do not run the observation cycle - we do that ourselves in testing
}
- Set<WatchedFolder> getWatchedFolders() {
- return folders;
- }
-
boolean folderIsWatched(String path) throws Exception {
boolean result = false;
- for(WatchedFolder wf : folders) {
+ for(WatchedFolder wf : getWatchedFolders()) {
if(wf.getPath().equals("/" + path)) {
result = true;
break;
Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java?rev=722457&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java Tue Dec 2 05:48:48 2008
@@ -0,0 +1,36 @@
+package org.apache.sling.jcr.jcrinstall.jcr.impl;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.startlevel.StartLevel;
+
+public class MockStartLevel implements StartLevel {
+
+ public int getBundleStartLevel(Bundle arg0) {
+ return 0;
+ }
+
+ public int getInitialBundleStartLevel() {
+ return 0;
+ }
+
+ public int getStartLevel() {
+ return 0;
+ }
+
+ public boolean isBundleActivationPolicyUsed(Bundle arg0) {
+ return false;
+ }
+
+ public boolean isBundlePersistentlyStarted(Bundle arg0) {
+ return false;
+ }
+
+ public void setBundleStartLevel(Bundle arg0, int arg1) {
+ }
+
+ public void setInitialBundleStartLevel(int arg0) {
+ }
+
+ public void setStartLevel(int arg0) {
+ }
+}
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockStartLevel.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java Tue Dec 2 05:48:48 2008
@@ -250,10 +250,14 @@
allowing(c).executeScheduledOperations();
allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
allowing(c).getInstalledUris(); will(returnValue(installedUri));
- allowing(c).getDigest(with(any(String.class))); will(returnValue(null));
- one(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
- one(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
- one(c).scheduleUninstall("/libs/watchfolder-is-gone/install/gone.cfg");
+ allowing(c).getDigest(with(any(String.class))); will(returnValue(null));
+
+ // scheduleUninstall might be called multiple times for the same resource
+ // during the initial deletion analysis - the OsgiController needs to accept
+ // such multiple calls
+ atLeast(1).of(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
+ atLeast(1).of(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
+ atLeast(1).of(c).scheduleUninstall("/libs/watchfolder-is-gone/install/gone.cfg");
}});
ro.activate(null);
@@ -272,17 +276,18 @@
final OsgiController c = mockery.mock(OsgiController.class);
final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
+ // See testInitialDeletions() about multiple scheduleUninstall calls
mockery.checking(new Expectations() {{
allowing(c).executeScheduledOperations();
allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
allowing(c).getInstalledUris(); will(returnValue(installedUri));
allowing(c).getDigest(with(any(String.class))); will(returnValue(null));
- one(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
+ atLeast(1).of(c).scheduleUninstall("/libs/foo/bar/install/dummy.cfg");
inSequence(sequence);
- one(c).scheduleUninstall("/libs/foo/bar/install/dummy.dp");
+ atLeast(1).of(c).scheduleUninstall("/libs/foo/bar/install/dummy.dp");
inSequence(sequence);
will(throwException(new JcrInstallException("Fake BundleException for testing")));
- one(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
+ atLeast(1).of(c).scheduleUninstall("/libs/foo/bar/install/dummy.jar");
inSequence(sequence);
}});
@@ -360,8 +365,8 @@
allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
allowing(c).getInstalledUris(); will(returnValue(installedUri));
allowing(c).getDigest(with(any(String.class))); will(returnValue(null));
- one(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
- one(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
+ atLeast(1).of(c).scheduleInstallOrUpdate(with(equal(resources[0])), with(any(InstallableData.class)));
+ atLeast(1).of(c).scheduleInstallOrUpdate(with(equal(resources[2])), with(any(InstallableData.class)));
}});
final MockRepositoryObserver ro = new MockRepositoryObserver(repo, c, serviceDataFile);
@@ -384,10 +389,10 @@
allowing(c).setResourceOverrideRules(with(any(ResourceOverrideRules.class)));
allowing(c).getInstalledUris(); will(returnValue(installedUri));
allowing(c).getDigest(with(any(String.class))); will(returnValue(null));
- one(c).scheduleUninstall(resources[0]);
- one(c).scheduleUninstall(resources[2]);
- one(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
- one(c).scheduleInstallOrUpdate(with(equal(resources[3])), with(any(InstallableData.class)));
+ atLeast(1).of(c).scheduleUninstall(resources[0]);
+ atLeast(1).of(c).scheduleUninstall(resources[2]);
+ atLeast(1).of(c).scheduleInstallOrUpdate(with(equal(resources[1])), with(any(InstallableData.class)));
+ atLeast(1).of(c).scheduleInstallOrUpdate(with(equal(resources[3])), with(any(InstallableData.class)));
}});
props.setProperty(RepositoryObserver.FOLDER_NAME_REGEXP_PROPERTY, ".*foo/wii/install$");
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessorTest.java Tue Dec 2 05:48:48 2008
@@ -29,7 +29,7 @@
import java.io.IOException;
import java.io.InputStream;
-import org.apache.sling.jcr.jcrinstall.osgi.InstallableData;
+import org.apache.sling.jcr.jcrinstall.jcr.impl.MockStartLevel;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.Sequence;
@@ -37,6 +37,7 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkListener;
import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
/** Test the BundleResourceProcessor */
public class BundleResourceProcessorTest {
@@ -104,7 +105,7 @@
}});
// Do the calls and check some stuff on the way
- final BundleResourceProcessor p = new BundleResourceProcessor(bc, pa);
+ final BundleResourceProcessor p = new BundleResourceProcessor(bc, pa, new MockStartLevel());
Utilities.setProcessors(c, p);
assertFalse("Before install, uri must not be in list", c.getInstalledUris().contains(uri));
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/MockInstallableData.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/MockInstallableData.java?rev=722457&r1=722456&r2=722457&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/MockInstallableData.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/MockInstallableData.java Tue Dec 2 05:48:48 2008
@@ -52,4 +52,8 @@
public String getDigest() {
return digest;
}
+
+ public int getBundleStartLevel() {
+ return 0;
+ }
}