Make OSGiBoot wait for bundles to be in status active or resolved
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 28 Jul 2009 13:42:04 +0000 (13:42 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 28 Jul 2009 13:42:04 +0000 (13:42 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2822 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java

index dbcb458f6ccab95902c6ad4d30538f8b7dfbb4d0..22a75989207db45571312070282df85f6ee9e993 100644 (file)
@@ -27,7 +27,10 @@ public class OsgiBoot {
        public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations";
        public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl";
        public final static String PROP_SLC_OSGI_MODULES_URL = "slc.osgi.modulesUrl";
+
        public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug";
+       public final static String PROP_SLC_OSGIBOOT_DEFAULT_TIMEOUT = "slc.osgiboot.defaultTimeout";
+       public final static String PROP_SLC_OSGIBOOT_MODULES_URL_SEPARATOR = "slc.osgiboot.modulesUrlSeparator";
 
        public final static String DEFAULT_BASE_URL = "reference:file:";
        public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**";
@@ -35,14 +38,21 @@ public class OsgiBoot {
        private boolean debug = Boolean.valueOf(
                        System.getProperty(PROP_SLC_OSGIBOOT_DEBUG, "false"))
                        .booleanValue();
+       /** Default is 10s (set in constructor) */
+       private long defaultTimeout;
 
        private boolean excludeSvn = true;
+       /** Default is ',' (set in constructor) */
        private String modulesUrlSeparator = ",";
 
        private final BundleContext bundleContext;
 
        public OsgiBoot(BundleContext bundleContext) {
                this.bundleContext = bundleContext;
+               defaultTimeout = Long.parseLong(getProperty(
+                               PROP_SLC_OSGIBOOT_DEFAULT_TIMEOUT, "10000"));
+               modulesUrlSeparator = getProperty(
+                               PROP_SLC_OSGIBOOT_MODULES_URL_SEPARATOR, ",");
        }
 
        public void bootstrap() {
@@ -147,7 +157,14 @@ public class OsgiBoot {
                        String symbolicName = bundle.getSymbolicName();
                        if (bundlesToStart.contains(symbolicName))
                                try {
-                                       bundle.start();
+                                       try {
+                                               bundle.start();
+                                       } catch (Exception e) {
+                                               // start failed, maybe bundle is not yet resolved
+                                               waitForBundleResolvedOrActive(bundle);
+                                               bundle.start();
+                                       }
+
                                        notStartedBundles.remove(symbolicName);
                                } catch (Exception e) {
                                        warn("Bundle " + symbolicName + " cannot be started: "
@@ -160,6 +177,53 @@ public class OsgiBoot {
                                        + " not started because it was not found.");
        }
 
+       protected void waitForBundleResolvedOrActive(Bundle bundle)
+                       throws Exception {
+               int originalState = bundle.getState();
+               if ((originalState == Bundle.RESOLVED)
+                               || (originalState == Bundle.ACTIVE))
+                       return;
+
+               String originalStateStr = stateAsString(originalState);
+
+               long begin = System.currentTimeMillis();
+               while ((bundle.getState() != Bundle.RESOLVED)
+                               || (bundle.getState() != Bundle.ACTIVE)) {
+                       long now = System.currentTimeMillis();
+                       if ((now - begin) > defaultTimeout)
+                               throw new Exception("Bundle " + bundle.getSymbolicName()
+                                               + " was not RESOLVED or ACTIVE after " + (now - begin)
+                                               + "ms (originalState=" + originalStateStr
+                                               + ", currentState=" + stateAsString(bundle.getState())
+                                               + ")");
+
+                       try {
+                               Thread.sleep(100l);
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+               }
+       }
+
+       public static String stateAsString(int state) {
+               switch (state) {
+               case Bundle.UNINSTALLED:
+                       return "UNINSTALLED";
+               case Bundle.INSTALLED:
+                       return "INSTALLED";
+               case Bundle.RESOLVED:
+                       return "RESOLVED";
+               case Bundle.STARTING:
+                       return "STARTING";
+               case Bundle.ACTIVE:
+                       return "ACTIVE";
+               case Bundle.STOPPING:
+                       return "STOPPING";
+               default:
+                       return Integer.toString(state);
+               }
+       }
+
        /** Key is location */
        public Map getInstalledBundles() {
                Map installedBundles = new HashMap();
@@ -569,4 +633,12 @@ public class OsgiBoot {
 
        }
 
+       public void setDefaultTimeout(long defaultTimeout) {
+               this.defaultTimeout = defaultTimeout;
+       }
+
+       public void setModulesUrlSeparator(String modulesUrlSeparator) {
+               this.modulesUrlSeparator = modulesUrlSeparator;
+       }
+
 }