From f40fc2eb2a212596df7a2855684f43d0204504d5 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Fri, 9 Nov 2012 10:29:46 +0000 Subject: [PATCH] OSGi boot supports start levels git-svn-id: https://svn.argeo.org/commons/trunk@5765 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../java/org/argeo/osgi/boot/OsgiBoot.java | 215 +++++++++++++----- 1 file changed, 164 insertions(+), 51 deletions(-) diff --git a/base/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/osgi/boot/OsgiBoot.java b/base/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/osgi/boot/OsgiBoot.java index 465ba9681..8d07219df 100644 --- a/base/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/osgi/boot/OsgiBoot.java +++ b/base/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/osgi/boot/OsgiBoot.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.SortedMap; import java.util.StringTokenizer; @@ -52,6 +53,9 @@ public class OsgiBoot { public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot"; public final static String SYMBOLIC_NAME_EQUINOX = "org.eclipse.osgi"; + public final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel"; + public final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel"; + public final static String PROP_ARGEO_OSGI_DATA_DIR = "argeo.osgi.data.dir"; public final static String PROP_ARGEO_OSGI_START = "argeo.osgi.start"; @@ -264,57 +268,88 @@ public class OsgiBoot { } } - /* @deprecated Doesn't seem to be used anymore. */ - // public void installOrUpdateUrls(Map urls) { - // Map installedBundles = getBundles(); - // - // for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) { - // String moduleName = (String) modules.next(); - // String urlStr = (String) urls.get(moduleName); - // if (installedBundles.containsKey(moduleName)) { - // Bundle bundle = (Bundle) installedBundles.get(moduleName); - // InputStream in; - // try { - // URL url = new URL(urlStr); - // in = url.openStream(); - // bundle.update(in); - // OsgiBootUtils.info("Updated bundle " + moduleName - // + " from " + urlStr); - // } catch (Exception e) { - // throw new RuntimeException("Cannot update " + moduleName - // + " from " + urlStr); - // } - // if (in != null) - // try { - // in.close(); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } else { - // try { - // Bundle bundle = bundleContext.installBundle(urlStr); - // if (debug) - // debug("Installed bundle " + bundle.getSymbolicName() - // + " from " + urlStr); - // } catch (BundleException e) { - // OsgiBootUtils.warn("Could not install bundle from " - // + urlStr + ": " + e.getMessage()); - // } - // } - // } - // - // } - /* * START */ public void startBundles() { - String bundlesToStart = OsgiBootUtils - .getProperty(PROP_ARGEO_OSGI_START); - startBundles(bundlesToStart); + // default and active start levels from System properties + Integer defaultStartLevel = new Integer(Integer.parseInt(OsgiBootUtils + .getProperty(PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL))); + Integer activeStartLevel = new Integer( + OsgiBootUtils.getProperty(PROP_OSGI_STARTLEVEL)); + + SortedMap/* > */startLevels = new TreeMap(); + computeStartLevels(startLevels, System.getProperties(), + defaultStartLevel); + + Iterator/* */levels = startLevels.keySet().iterator(); + while (levels.hasNext()) { + Integer level = (Integer) levels.next(); + boolean allStarted = startBundles((List) startLevels.get(level)); + if (!allStarted) + OsgiBootUtils + .warn("Not all bundles started for level " + level); + if (level.equals(activeStartLevel)) + break;// active start level reached + } + + } + + public static void computeStartLevels( + SortedMap/* > */startLevels, + Properties properties, Integer defaultStartLevel) { + + // default (and previously, only behaviour) + appendToStartLevels(startLevels, defaultStartLevel, + properties.getProperty(PROP_ARGEO_OSGI_START, "")); + + // list argeo.osgi.start.* system properties + Iterator/* */keys = properties.keySet().iterator(); + final String prefix = PROP_ARGEO_OSGI_START + "."; + while (keys.hasNext()) { + String key = (String) keys.next(); + if (key.startsWith(prefix)) { + Integer startLevel; + String suffix = key.substring(prefix.length()); + String[] tokens = suffix.split("\\."); + if (tokens.length > 0 && !tokens[0].trim().equals("")) + try { + // first token is start level + startLevel = new Integer(tokens[0]); + } catch (NumberFormatException e) { + startLevel = defaultStartLevel; + } + else + startLevel = defaultStartLevel; + + // append bundle names + String bundleNames = properties.getProperty(key); + appendToStartLevels(startLevels, startLevel, bundleNames); + } + } + } + + /** Append a comma-separated list of bundles to the start levels. */ + private static void appendToStartLevels( + SortedMap/* > */startLevels, + Integer startLevel, String str) { + if (str == null || str.trim().equals("")) + return; + + if (!startLevels.containsKey(startLevel)) + startLevels.put(startLevel, new ArrayList()); + String[] bundleNames = str.split(","); + for (int i = 0; i < bundleNames.length; i++) { + if (bundleNames[i] != null && !bundleNames[i].trim().equals("")) + ((List) startLevels.get(startLevel)).add(bundleNames[i]); + } } - /** Convenience method accepting a comma-separated list of bundle to start */ + /** + * Convenience method accepting a comma-separated list of bundle to start + * + * @deprecated + */ public void startBundles(String bundlesToStartStr) { if (bundlesToStartStr == null) return; @@ -328,13 +363,19 @@ public class OsgiBoot { startBundles(bundlesToStart); } - /** Start the provided list of bundles */ - public void startBundles(List bundlesToStart) { + /** + * Start the provided list of bundles + * + * @return whether all bundlesa are now in active state + */ + public boolean startBundles(List bundlesToStart) { if (bundlesToStart.size() == 0) - return; + return true; + // used to monitor ACTIVE states + List/* */startedBundles = new ArrayList(); // used to log the bundles not found - List notFoundBundles = new ArrayList(bundlesToStart); + List/* */notFoundBundles = new ArrayList(bundlesToStart); Bundle[] bundles = bundleContext.getBundles(); long startBegin = System.currentTimeMillis(); @@ -354,6 +395,7 @@ public class OsgiBoot { + " waiting and trying again."); waitForBundleResolvedOrActive(startBegin, bundle); bundle.start(); + startedBundles.add(bundle); } notFoundBundles.remove(symbolicName); } catch (Exception e) { @@ -367,8 +409,38 @@ public class OsgiBoot { } for (int i = 0; i < notFoundBundles.size(); i++) - OsgiBootUtils.warn("Bundle " + notFoundBundles.get(i) - + " not started because it was not found."); + OsgiBootUtils.warn("Bundle '" + notFoundBundles.get(i) + + "' not started because it was not found."); + + // monitors that all bundles are started + long beginMonitor = System.currentTimeMillis(); + boolean allStarted = false; + List/* */notStarted = new ArrayList(); + while (allStarted + && (System.currentTimeMillis() - beginMonitor) > defaultTimeout) { + notStarted = new ArrayList(); + for (int i = 0; i < startedBundles.size(); i++) { + Bundle bundle = (Bundle) startedBundles.get(i); + // TODO check behaviour of lazs bundles + if (bundle.getState() != Bundle.ACTIVE) { + allStarted = false; + notStarted.add(bundle.getSymbolicName()); + } + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // silent + } + } + long duration = System.currentTimeMillis() - beginMonitor; + + if (!allStarted) + for (int i = 0; i < notStarted.size(); i++) + OsgiBootUtils.warn("Bundle '" + notStarted.get(i) + + "' not ACTIVE after " + (duration / 1000) + "s"); + + return allStarted; } /* @@ -919,4 +991,45 @@ public class OsgiBoot { } + /* @deprecated Doesn't seem to be used anymore. */ + // public void installOrUpdateUrls(Map urls) { + // Map installedBundles = getBundles(); + // + // for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) { + // String moduleName = (String) modules.next(); + // String urlStr = (String) urls.get(moduleName); + // if (installedBundles.containsKey(moduleName)) { + // Bundle bundle = (Bundle) installedBundles.get(moduleName); + // InputStream in; + // try { + // URL url = new URL(urlStr); + // in = url.openStream(); + // bundle.update(in); + // OsgiBootUtils.info("Updated bundle " + moduleName + // + " from " + urlStr); + // } catch (Exception e) { + // throw new RuntimeException("Cannot update " + moduleName + // + " from " + urlStr); + // } + // if (in != null) + // try { + // in.close(); + // } catch (IOException e) { + // e.printStackTrace(); + // } + // } else { + // try { + // Bundle bundle = bundleContext.installBundle(urlStr); + // if (debug) + // debug("Installed bundle " + bundle.getSymbolicName() + // + " from " + urlStr); + // } catch (BundleException e) { + // OsgiBootUtils.warn("Could not install bundle from " + // + urlStr + ": " + e.getMessage()); + // } + // } + // } + // + // } + } -- 2.30.2