From: Mathieu Baudier Date: Tue, 11 Apr 2017 17:43:33 +0000 (+0200) Subject: OSGi boot can update a non emptry configuration area X-Git-Tag: argeo-commons-2.1.68~2 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=86e5f79860a8b3013b40a36c1f06c828d52f5249 OSGi boot can update a non emptry configuration area --- diff --git a/demo/argeo_node_osgiboot.properties b/demo/argeo_node_osgiboot.properties index 713c80c0e..09baf13fa 100644 --- a/demo/argeo_node_osgiboot.properties +++ b/demo/argeo_node_osgiboot.properties @@ -1,14 +1,10 @@ -#argeo.osgi.bundles=/home/mbaudier/dev/src/commons/dep/org.argeo.dep.cms.node/target/dependency;in=*.jar - -#argeo.osgi.baseUrl=http://forge.argeo.org/data/public/java/argeo-2.1/ -#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.node/2.1.45/org.argeo.dep.cms.node-2.1.45.jar +argeo.osgi.baseUrl=http://forge.argeo.org/data/java/argeo-2.1/ +argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.65/org.argeo.dep.cms.sdk-2.1.65.jar +#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.67/org.argeo.dep.cms.sdk-2.1.67.jar #argeo.osgi.baseUrl=file:///home/mbaudier/.m2/repository/ -argeo.osgi.baseUrl=http://forge.argeo.org/data/java/argeo-2.1/ -argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.node/2.1.65/org.argeo.dep.cms.node-2.1.65.jar -#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.node/2.1.66-SNAPSHOT/org.argeo.dep.cms.node-2.1.66-SNAPSHOT.jar +#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.68-SNAPSHOT/org.argeo.dep.cms.sdk-2.1.68-SNAPSHOT.jar -#argeo.osgi.distributionUrl=http://forge.argeo.org/data/public/java/argeo-2.1/org/argeo/commons/org.argeo.dep.cms.node/2.1.40/org.argeo.dep.cms.node-2.1.40.jar argeo.osgi.boot.debug=true argeo.osgi.start.1.osgiboot=org.argeo.osgi.boot @@ -19,57 +15,9 @@ org.osgi.framework.security=osgi java.security.policy=file:../../all.policy argeo.node.repo.type=localfs - -#argeo.node.useradmin.uris=ldap://uid=admin,ou=system:secret@localhost:10389/dc=example,dc=com -#argeo.node.useradmin.uris=ldap://uid=admin,ou=system:secret@localhost:10389\ -#/dc=example,dc=com?userBase=ou=users&groupBase=ou=groups - -#argeo.node.useradmin.uris="\ -#ldap://uid=admin,ou=system:secret\ -#@localhost:10389\ -#/dc=example,dc=com\ -#?readOnly=false\ -#&userObjectClass=inetOrgPerson \ -#dc=example,dc=org.ldif" - -#argeo.node.useradmin.uris="dc=example,dc=com.ldif dc=example,dc=org.ldif" - -# HTTP org.osgi.service.http.port=7070 -#org.eclipse.equinox.http.jetty.log.stderr.threshold=info - -# HTTPS -#org.osgi.service.http.port.secure=7073 -#org.eclipse.equinox.http.jetty.https.enabled=true -#org.eclipse.equinox.http.jetty.ssl.keystore=../../ssl/server.jks -#org.eclipse.equinox.http.jetty.ssl.keystore=data/node.p12 -#org.eclipse.equinox.http.jetty.ssl.keystoretype=PKCS12 -#org.eclipse.equinox.http.jetty.ssl.password=changeit -#org.eclipse.equinox.http.jetty.ssl.wantclientauth=true - -# In order to configure demo certificates, run: -# cd ssl; sh ./ssl.sh; - -# i18n -argeo.i18n.locales=en,fr,ru -eclipse.registry.MultiLanguage=true -#argeo.i18n.defaultLocale=en - -# Logging log4j.configuration=file:../../log4j.properties -# Tuning -# Number of DB connections -#argeo.node.repo.maxPoolSize=10 -# Max amount of memory available to Jackrabbit caches -#argeo.node.repo.maxCacheMB=16 -# Persistence level cache -#argeo.node.repo.bundleCacheMB=8 -# Search, see http://wiki.apache.org/jackrabbit/Search -#argeo.node.repo.extractorPoolSize=0 -#argeo.node.repo.searchCacheSize=1000 -#argeo.node.repo.maxVolatileIndexSize=1048576 - # DON'T CHANGE BELOW org.eclipse.rap.workbenchAutostart=false org.eclipse.equinox.http.jetty.autostart=false \ No newline at end of file diff --git a/org.argeo.osgi.boot/ext/test/org/argeo/osgi/boot/OsgiBootNoRuntimeTest.java b/org.argeo.osgi.boot/ext/test/org/argeo/osgi/boot/OsgiBootNoRuntimeTest.java index 6a8ac1683..c667f918e 100644 --- a/org.argeo.osgi.boot/ext/test/org/argeo/osgi/boot/OsgiBootNoRuntimeTest.java +++ b/org.argeo.osgi.boot/ext/test/org/argeo/osgi/boot/OsgiBootNoRuntimeTest.java @@ -44,7 +44,7 @@ public class OsgiBootNoRuntimeTest extends TestCase { String baseUrl = "file:"; String bundles = BUNDLES; OsgiBoot osgiBoot = new OsgiBoot(null); - osgiBoot.setExcludeSvn(true); +// osgiBoot.setExcludeSvn(true); List urls = osgiBoot.getBundlesUrls(baseUrl, bundles); for (int i = 0; i < urls.size(); i++) System.out.println(urls.get(i)); diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/BundlesSet.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/BundlesSet.java new file mode 100644 index 000000000..4a342fdbe --- /dev/null +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/BundlesSet.java @@ -0,0 +1,71 @@ +package org.argeo.osgi.boot; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** Intermediary structure used by path matching */ +class BundlesSet { + private String baseUrl = "reference:file";// not used yet + private final String dir; + private List includes = new ArrayList(); + private List excludes = new ArrayList(); + + public BundlesSet(String def) { + StringTokenizer st = new StringTokenizer(def, ";"); + + if (!st.hasMoreTokens()) + throw new RuntimeException("Base dir not defined."); + try { + String dirPath = st.nextToken(); + + if (dirPath.startsWith("file:")) + dirPath = dirPath.substring("file:".length()); + + dir = new File(dirPath.replace('/', File.separatorChar)).getCanonicalPath(); + if (OsgiBootUtils.debug) + OsgiBootUtils.debug("Base dir: " + dir); + } catch (IOException e) { + throw new RuntimeException("Cannot convert to absolute path", e); + } + + while (st.hasMoreTokens()) { + String tk = st.nextToken(); + StringTokenizer stEq = new StringTokenizer(tk, "="); + String type = stEq.nextToken(); + String pattern = stEq.nextToken(); + if ("in".equals(type) || "include".equals(type)) { + includes.add(pattern); + } else if ("ex".equals(type) || "exclude".equals(type)) { + excludes.add(pattern); + } else if ("baseUrl".equals(type)) { + baseUrl = pattern; + } else { + System.err.println("Unkown bundles pattern type " + type); + } + } + + // if (excludeSvn && !excludes.contains(EXCLUDES_SVN_PATTERN)) { + // excludes.add(EXCLUDES_SVN_PATTERN); + // } + } + + public String getDir() { + return dir; + } + + public List getIncludes() { + return includes; + } + + public List getExcludes() { + return excludes; + } + + public String getBaseUrl() { + return baseUrl; + } + +} diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java index f481473a2..0d0cb9321 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/DistributionBundle.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.DirectoryStream; import java.nio.file.Files; @@ -58,6 +59,7 @@ public class DistributionBundle { private String baseUrl; /** can be null */ private String relativeUrl; + private String localCache; private List artifacts; @@ -67,7 +69,7 @@ public class DistributionBundle { this.url = url; } - public DistributionBundle(String baseUrl, String relativeUrl) { + public DistributionBundle(String baseUrl, String relativeUrl, String localCache) { if (baseUrl == null || !baseUrl.endsWith("/")) throw new OsgiBootException("Base url " + baseUrl + " badly formatted"); if (relativeUrl.startsWith("http") || relativeUrl.startsWith("file:")) @@ -75,6 +77,7 @@ public class DistributionBundle { this.url = constructUrl(baseUrl, relativeUrl); this.baseUrl = baseUrl; this.relativeUrl = relativeUrl; + this.localCache = localCache; } protected String constructUrl(String baseUrl, String relativeUrl) { @@ -96,34 +99,6 @@ public class DistributionBundle { if (res.size() == 0) throw new OsgiBootException("No file matching " + relativeUrl + " found in " + baseUrl); return res.get(res.firstKey()).toUri().toString(); - // try (DirectoryStream ds = - // Files.newDirectoryStream(basePath)) { - // Path res = null; - // for (Path path : ds) { - // if (pm.matches(path)) { - // if (res == null) - // res = path; - // else - // throw new OsgiBootException( - // "More than one file matching " + relativeUrl + " found in " + - // baseUrl); - // } - // } - // if (res == null) - // throw new OsgiBootException("No file matching " + relativeUrl - // + " found in " + baseUrl); - // return res.toUri().toURL().toString(); - // // Iterator it = ds.iterator(); - // // if (!it.hasNext()) - // // throw new OsgiBootException("No file matching " + - // // relativeUrl + " found in " + baseUrl); - // // Path distributionBundlePath = it.next(); - // // if (it.hasNext())// TODO implement version ordered - // // throw new OsgiBootException( - // // "More than one file matching " + relativeUrl + " found in - // // " + baseUrl); - // // return distributionBundlePath.toUri().toURL().toString(); - // } } else { return baseUrl + relativeUrl; } @@ -150,30 +125,16 @@ public class DistributionBundle { } } - // public static void main(String[] args) { - // try { - // String baseUrl = "file:///home/mbaudier/.m2/repository/"; - // String relativeUrl = - // "org/argeo/commons/org.argeo.dep.cms.node/2.1.*-SNAPSHOT/org.argeo.dep.cms.node-2.1.*-SNAPSHOT.jar"; - // Path basePath = Paths.get(new URI(baseUrl)); - // PathMatcher pm = basePath.getFileSystem().getPathMatcher("glob:" + - // relativeUrl); - // - // try (DirectoryStream ds = Files.newDirectoryStream(basePath, "**")) - // { - // for (Path path : ds) { - // System.out.println(path); - // } - // } - // } catch (Exception e) { - // e.printStackTrace(); - // } - // } - public void processUrl() { JarInputStream jarIn = null; try { URL u = new URL(url); + + // local cache + URI localUri = new URI(localCache + relativeUrl); + Path localPath = Paths.get(localUri); + if (Files.exists(localPath)) + u = localUri.toURL(); jarIn = new JarInputStream(u.openStream()); // meta data @@ -240,8 +201,8 @@ public class DistributionBundle { } /** Convenience method */ - public static DistributionBundle processUrl(String baseUrl, String realtiveUrl) { - DistributionBundle distributionBundle = new DistributionBundle(baseUrl, realtiveUrl); + public static DistributionBundle processUrl(String baseUrl, String realtiveUrl, String localCache) { + DistributionBundle distributionBundle = new DistributionBundle(baseUrl, realtiveUrl, localCache); distributionBundle.processUrl(); return distributionBundle; } @@ -260,7 +221,21 @@ public class DistributionBundle { List urls = new ArrayList(); for (int i = 0; i < artifacts.size(); i++) { OsgiArtifact osgiArtifact = (OsgiArtifact) artifacts.get(i); - urls.add(baseUrl + osgiArtifact.getRelativeUrl()); + // local cache + URI localUri; + try { + localUri = new URI(localCache + relativeUrl); + } catch (URISyntaxException e) { + OsgiBootUtils.warn(e.getMessage()); + localUri = null; + } + Version version = new Version(osgiArtifact.getVersion()); + if (localUri != null && Files.exists(Paths.get(localUri)) + && version.getQualifier()!=null && version.getQualifier().startsWith("SNAPSHOT")) { + urls.add(localCache + osgiArtifact.getRelativeUrl()); + } else { + urls.add(baseUrl + osgiArtifact.getRelativeUrl()); + } } return urls; } diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java index bd49d99d4..f44642d52 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBoot.java @@ -19,7 +19,6 @@ import static org.argeo.osgi.boot.OsgiBootUtils.debug; import static org.argeo.osgi.boot.OsgiBootUtils.warn; import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -38,8 +37,10 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.FrameworkEvent; +import org.osgi.framework.Version; import org.osgi.framework.startlevel.BundleStartLevel; import org.osgi.framework.startlevel.FrameworkStartLevel; +import org.osgi.framework.wiring.FrameworkWiring; /** * Basic provisioning of an OSGi runtime via file path patterns and system @@ -47,46 +48,44 @@ import org.osgi.framework.startlevel.FrameworkStartLevel; * methods, configured via properties. */ public class OsgiBoot implements OsgiBootConstants { - // public final static String PROP_ARGEO_OSGI_DATA_DIR = - // "argeo.osgi.data.dir"; public final static String PROP_ARGEO_OSGI_START = "argeo.osgi.start"; public final static String PROP_ARGEO_OSGI_BUNDLES = "argeo.osgi.bundles"; public final static String PROP_ARGEO_OSGI_BASE_URL = "argeo.osgi.baseUrl"; + public final static String PROP_ARGEO_OSGI_LOCAL_CACHE = "argeo.osgi.localCache"; public final static String PROP_ARGEO_OSGI_DISTRIBUTION_URL = "argeo.osgi.distributionUrl"; // booleans public final static String PROP_ARGEO_OSGI_BOOT_DEBUG = "argeo.osgi.boot.debug"; - public final static String PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN = "argeo.osgi.boot.excludeSvn"; + // public final static String PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN = + // "argeo.osgi.boot.excludeSvn"; - // public final static String PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT = - // "argeo.osgi.boot.defaultTimeout"; public final static String PROP_ARGEO_OSGI_BOOT_SYSTEM_PROPERTIES_FILE = "argeo.osgi.boot.systemPropertiesFile"; public final static String PROP_ARGEO_OSGI_BOOT_APPCLASS = "argeo.osgi.boot.appclass"; public final static String PROP_ARGEO_OSGI_BOOT_APPARGS = "argeo.osgi.boot.appargs"; public final static String DEFAULT_BASE_URL = "reference:file:"; - public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**"; + // public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**"; // OSGi system properties public final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel"; public final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel"; public final static String INSTANCE_AREA_PROP = "osgi.instance.area"; - // public final static String INSTANCE_AREA_DEFAULT_PROP = - // "osgi.instance.area.default"; // Symbolic names public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot"; public final static String SYMBOLIC_NAME_EQUINOX = "org.eclipse.osgi"; - private boolean debug = Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_DEBUG, "false")).booleanValue(); /** Exclude svn metadata implicitely(a bit costly) */ - private boolean excludeSvn = Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN, "false")) - .booleanValue(); + // private boolean excludeSvn = + // Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN, + // "false")) + // .booleanValue(); /** Default is 10s */ - private long defaultTimeout = 10000l; + // private long defaultTimeout = 10000l; private final BundleContext bundleContext; + private final String localCache; /* * INITIALIZATION @@ -94,38 +93,10 @@ public class OsgiBoot implements OsgiBootConstants { /** Constructor */ public OsgiBoot(BundleContext bundleContext) { this.bundleContext = bundleContext; - // defaultTimeout = - // Long.parseLong(OsgiBootUtils.getProperty(PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT, - // "10000")); - // initSystemProperties(); + localCache = getProperty(PROP_ARGEO_OSGI_LOCAL_CACHE, + "file://" + System.getProperty("user.home") + "/.m2/repository/"); } - // /** - // * Set additional system properties, especially ${argeo.osgi.data.dir} as - // an - // * OS file path (and not a file:// URL) - // */ - // private void initSystemProperties() { - // String osgiInstanceArea = System.getProperty(INSTANCE_AREA_PROP); - // String osgiInstanceAreaDefault = - // System.getProperty(INSTANCE_AREA_DEFAULT_PROP); - // String tempDir = System.getProperty("java.io.tmpdir"); - // - // File dataDir = null; - // if (osgiInstanceArea != null) { - // // within OSGi with -data specified - // osgiInstanceArea = removeFilePrefix(osgiInstanceArea); - // dataDir = new File(osgiInstanceArea); - // } else if (osgiInstanceAreaDefault != null) { - // // within OSGi without -data specified - // osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault); - // dataDir = new File(osgiInstanceAreaDefault); - // } else {// outside OSGi - // dataDir = new File(tempDir + File.separator + "argeoOsgiData"); - // } - // System.setProperty(PROP_ARGEO_OSGI_DATA_DIR, dataDir.getAbsolutePath()); - // } - /* * HIGH-LEVEL METHODS */ @@ -137,9 +108,6 @@ public class OsgiBoot implements OsgiBootConstants { String osgiInstancePath = bundleContext.getProperty(INSTANCE_AREA_PROP); OsgiBootUtils .info("OSGi bootstrap starting" + (osgiInstancePath != null ? " (" + osgiInstancePath + ")" : "")); - // OsgiBootUtils.info("Writable data directory : " + - // System.getProperty(PROP_ARGEO_OSGI_DATA_DIR) - // + " (set as system property " + PROP_ARGEO_OSGI_DATA_DIR + ")"); installUrls(getBundlesUrls()); installUrls(getDistributionUrls()); startBundles(); @@ -152,7 +120,7 @@ public class OsgiBoot implements OsgiBootConstants { } // diagnostics - if (debug) { + if (OsgiBootUtils.debug) { OsgiBootDiagnostics diagnostics = new OsgiBootDiagnostics(bundleContext); diagnostics.checkUnresolved(); Map> duplicatePackages = diagnostics.findPackagesExportedTwice(); @@ -190,6 +158,7 @@ public class OsgiBoot implements OsgiBootConstants { String url = (String) urls.get(i); installUrl(url, installedBundles); } + refreshFramework(); } /** Actually install the provided URL */ @@ -197,11 +166,11 @@ public class OsgiBoot implements OsgiBootConstants { try { if (installedBundles.containsKey(url)) { Bundle bundle = (Bundle) installedBundles.get(url); - if (debug) + if (OsgiBootUtils.debug) debug("Bundle " + bundle.getSymbolicName() + " already installed from " + url); } else if (url.contains("/" + SYMBOLIC_NAME_EQUINOX + "/") || url.contains("/" + SYMBOLIC_NAME_OSGI_BOOT + "/")) { - if (debug) + if (OsgiBootUtils.debug) warn("Skip " + url); return; } else { @@ -209,9 +178,34 @@ public class OsgiBoot implements OsgiBootConstants { if (url.startsWith("http")) OsgiBootUtils .info("Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url); - else if (debug) + else if (OsgiBootUtils.debug) OsgiBootUtils.debug( "Installed " + bundle.getSymbolicName() + "-" + bundle.getVersion() + " from " + url); + // uninstall previous versions + bundles: for (Bundle b : bundleContext.getBundles()) { + if (bundle.getSymbolicName().equals(b.getSymbolicName())) { + Version bundleV = bundle.getVersion(); + Version bV = b.getVersion(); + if (bundleV.getMajor() == bV.getMajor() && bundleV.getMinor() == bV.getMinor()) { + if (bundleV.getMicro() > bV.getMicro()) { + // uninstall older bundles + b.uninstall(); + OsgiBootUtils.debug("Uninstalled " + b); + } else if (bundleV.getMicro() < bV.getMicro()) { + // uninstall just installed bundle if newer + bundle.uninstall(); + OsgiBootUtils.debug("Uninstalled " + bundle); + break bundles; + } else { + // uninstall any other with same major/minor + if (!bundleV.getQualifier().equals(bV.getQualifier())) { + b.uninstall(); + OsgiBootUtils.debug("Uninstalled " + b); + } + } + } + } + } } } catch (BundleException e) { String message = e.getMessage(); @@ -223,7 +217,7 @@ public class OsgiBoot implements OsgiBootConstants { } else { OsgiBootUtils.warn("Could not install bundle from " + url + ": " + message); } - if (debug) + if (OsgiBootUtils.debug && !message.contains("is already installed")) e.printStackTrace(); } } @@ -275,17 +269,6 @@ public class OsgiBoot implements OsgiBootConstants { int startLevel = frameworkStartLevel.getStartLevel(); OsgiBootUtils.debug("Framework start level: " + startLevel + " (initial: " + initialStartLevel + ")"); }); - - // Iterator levels = startLevels.keySet().iterator(); - // while (levels.hasNext()) { - // Integer level = (Integer) levels.next(); - // boolean allStarted = startBundles(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, @@ -341,101 +324,111 @@ public class OsgiBoot implements OsgiBootConstants { * @return whether all bundles are now in active state * @deprecated */ - @Deprecated - public boolean startBundles(List bundlesToStart) { - if (bundlesToStart.size() == 0) - return true; - - // used to monitor ACTIVE states - List startedBundles = new ArrayList(); - // used to log the bundles not found - List notFoundBundles = new ArrayList(bundlesToStart); - - Bundle[] bundles = bundleContext.getBundles(); - long startBegin = System.currentTimeMillis(); - for (int i = 0; i < bundles.length; i++) { - Bundle bundle = bundles[i]; - String symbolicName = bundle.getSymbolicName(); - if (bundlesToStart.contains(symbolicName)) - try { - try { - bundle.start(); - if (debug) - debug("Bundle " + symbolicName + " started"); - } catch (Exception e) { - OsgiBootUtils.warn("Start of bundle " + symbolicName + " failed because of " + e - + ", maybe bundle is not yet resolved," + " waiting and trying again."); - waitForBundleResolvedOrActive(startBegin, bundle); - bundle.start(); - startedBundles.add(bundle); - } - notFoundBundles.remove(symbolicName); - } catch (Exception e) { - OsgiBootUtils.warn("Bundle " + symbolicName + " cannot be started: " + e.getMessage()); - if (debug) - e.printStackTrace(); - // was found even if start failed - notFoundBundles.remove(symbolicName); - } - } - - for (int i = 0; i < notFoundBundles.size(); i++) - 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 = !(startedBundles.size() > 0); - List notStarted = new ArrayList(); - while (!allStarted && (System.currentTimeMillis() - beginMonitor) < defaultTimeout) { - notStarted = new ArrayList(); - allStarted = true; - 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; - } + // @Deprecated + // public boolean startBundles(List bundlesToStart) { + // if (bundlesToStart.size() == 0) + // return true; + // + // // used to monitor ACTIVE states + // List startedBundles = new ArrayList(); + // // used to log the bundles not found + // List notFoundBundles = new ArrayList(bundlesToStart); + // + // Bundle[] bundles = bundleContext.getBundles(); + // long startBegin = System.currentTimeMillis(); + // for (int i = 0; i < bundles.length; i++) { + // Bundle bundle = bundles[i]; + // String symbolicName = bundle.getSymbolicName(); + // if (bundlesToStart.contains(symbolicName)) + // try { + // try { + // bundle.start(); + // if (OsgiBootUtils.debug) + // debug("Bundle " + symbolicName + " started"); + // } catch (Exception e) { + // OsgiBootUtils.warn("Start of bundle " + symbolicName + " failed because + // of " + e + // + ", maybe bundle is not yet resolved," + " waiting and trying again."); + // waitForBundleResolvedOrActive(startBegin, bundle); + // bundle.start(); + // startedBundles.add(bundle); + // } + // notFoundBundles.remove(symbolicName); + // } catch (Exception e) { + // OsgiBootUtils.warn("Bundle " + symbolicName + " cannot be started: " + + // e.getMessage()); + // if (OsgiBootUtils.debug) + // e.printStackTrace(); + // // was found even if start failed + // notFoundBundles.remove(symbolicName); + // } + // } + // + // for (int i = 0; i < notFoundBundles.size(); i++) + // 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 = !(startedBundles.size() > 0); + // List notStarted = new ArrayList(); + // while (!allStarted && (System.currentTimeMillis() - beginMonitor) < + // defaultTimeout) { + // notStarted = new ArrayList(); + // allStarted = true; + // 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; + // } /** Waits for a bundle to become active or resolved */ - private void waitForBundleResolvedOrActive(long startBegin, Bundle bundle) throws Exception { - int originalState = bundle.getState(); - if ((originalState == Bundle.RESOLVED) || (originalState == Bundle.ACTIVE)) - return; - - String originalStateStr = OsgiBootUtils.stateAsString(originalState); - - int currentState = bundle.getState(); - while (!(currentState == Bundle.RESOLVED || currentState == Bundle.ACTIVE)) { - long now = System.currentTimeMillis(); - if ((now - startBegin) > defaultTimeout * 10) - throw new Exception("Bundle " + bundle.getSymbolicName() + " was not RESOLVED or ACTIVE after " - + (now - startBegin) + "ms (originalState=" + originalStateStr + ", currentState=" - + OsgiBootUtils.stateAsString(currentState) + ")"); - - try { - Thread.sleep(100l); - } catch (InterruptedException e) { - // silent - } - currentState = bundle.getState(); - } - } + // private void waitForBundleResolvedOrActive(long startBegin, Bundle + // bundle) throws Exception { + // int originalState = bundle.getState(); + // if ((originalState == Bundle.RESOLVED) || (originalState == + // Bundle.ACTIVE)) + // return; + // + // String originalStateStr = OsgiBootUtils.stateAsString(originalState); + // + // int currentState = bundle.getState(); + // while (!(currentState == Bundle.RESOLVED || currentState == + // Bundle.ACTIVE)) { + // long now = System.currentTimeMillis(); + // if ((now - startBegin) > defaultTimeout * 10) + // throw new Exception("Bundle " + bundle.getSymbolicName() + " was not + // RESOLVED or ACTIVE after " + // + (now - startBegin) + "ms (originalState=" + originalStateStr + ", + // currentState=" + // + OsgiBootUtils.stateAsString(currentState) + ")"); + // + // try { + // Thread.sleep(100l); + // } catch (InterruptedException e) { + // // silent + // } + // currentState = bundle.getState(); + // } + // } /* * BUNDLE PATTERNS INSTALLATION @@ -469,8 +462,8 @@ public class OsgiBoot implements OsgiBootConstants { return urls; bundlePatterns = SystemPropertyUtils.resolvePlaceholders(bundlePatterns); - if (debug) - debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns + " (excludeSvn=" + excludeSvn + ")"); + if (OsgiBootUtils.debug) + debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns); StringTokenizer st = new StringTokenizer(bundlePatterns, ","); List bundlesSets = new ArrayList(); @@ -531,7 +524,7 @@ public class OsgiBoot implements OsgiBootConstants { DistributionBundle distributionBundle; if (baseUrl != null && !(distributionUrl.startsWith("http") || distributionUrl.startsWith("file"))) { // relative url - distributionBundle = new DistributionBundle(baseUrl, distributionUrl); + distributionBundle = new DistributionBundle(baseUrl, distributionUrl, localCache); } else { distributionBundle = new DistributionBundle(distributionUrl); if (baseUrl != null) @@ -553,7 +546,7 @@ public class OsgiBoot implements OsgiBootConstants { File[] files = baseDir.listFiles(); if (files == null) { - if (debug) + if (OsgiBootUtils.debug) OsgiBootUtils.warn("Base dir " + baseDir + " has no children, exists=" + baseDir.exists() + ", isDirectory=" + baseDir.isDirectory()); return; @@ -585,13 +578,13 @@ public class OsgiBoot implements OsgiBootConstants { // recurse only if start matches match(matcher, matched, base, newCurrentPath, pattern); } else { - if (debug) + if (OsgiBootUtils.debug) debug(newCurrentPath + " does not start match with " + pattern); } } else { boolean nonDirectoryOk = matcher.match(pattern, newCurrentPath); - if (debug) + if (OsgiBootUtils.debug) debug(currentPath + " " + (ok ? "" : " not ") + " matched with " + pattern); if (nonDirectoryOk) matched.add(relativeToFullPath(base, newCurrentPath)); @@ -645,14 +638,11 @@ public class OsgiBoot implements OsgiBootConstants { return (basePath + '/' + relativePath).replace('/', File.separatorChar); } - // private String removeFilePrefix(String url) { - // if (url.startsWith("file:")) - // return url.substring("file:".length()); - // else if (url.startsWith("reference:file:")) - // return url.substring("reference:file:".length()); - // else - // return url; - // } + private void refreshFramework() { + Bundle systemBundle = bundleContext.getBundle(0); + FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class); + frameworkWiring.refreshBundles(null); + } /** * Gets a property value @@ -661,20 +651,10 @@ public class OsgiBoot implements OsgiBootConstants { */ public String getProperty(String name, String defaultValue) { String value = bundleContext.getProperty(name); - if (value == null) + if (value == null) return defaultValue; // may be null else return value; - -// if (defaultValue != null) -// value = System.getProperty(name, defaultValue); -// else -// value = System.getProperty(name); -// -// if (value == null || value.equals("")) -// return null; -// else -// return value; } public String getProperty(String name) { @@ -686,12 +666,12 @@ public class OsgiBoot implements OsgiBootConstants { */ public boolean getDebug() { - return debug; + return OsgiBootUtils.debug; } - public void setDebug(boolean debug) { - this.debug = debug; - } + // public void setDebug(boolean debug) { + // this.debug = debug; + // } public BundleContext getBundleContext() { return bundleContext; @@ -701,79 +681,16 @@ public class OsgiBoot implements OsgiBootConstants { // this.defaultTimeout = defaultTimeout; // } - public boolean isExcludeSvn() { - return excludeSvn; - } - - public void setExcludeSvn(boolean excludeSvn) { - this.excludeSvn = excludeSvn; - } + // public boolean isExcludeSvn() { + // return excludeSvn; + // } + // + // public void setExcludeSvn(boolean excludeSvn) { + // this.excludeSvn = excludeSvn; + // } /* * INTERNAL CLASSES */ - /** Intermediary structure used by path matching */ - protected class BundlesSet { - private String baseUrl = "reference:file";// not used yet - private final String dir; - private List includes = new ArrayList(); - private List excludes = new ArrayList(); - - public BundlesSet(String def) { - StringTokenizer st = new StringTokenizer(def, ";"); - - if (!st.hasMoreTokens()) - throw new RuntimeException("Base dir not defined."); - try { - String dirPath = st.nextToken(); - - if (dirPath.startsWith("file:")) - dirPath = dirPath.substring("file:".length()); - - dir = new File(dirPath.replace('/', File.separatorChar)).getCanonicalPath(); - if (debug) - debug("Base dir: " + dir); - } catch (IOException e) { - throw new RuntimeException("Cannot convert to absolute path", e); - } - - while (st.hasMoreTokens()) { - String tk = st.nextToken(); - StringTokenizer stEq = new StringTokenizer(tk, "="); - String type = stEq.nextToken(); - String pattern = stEq.nextToken(); - if ("in".equals(type) || "include".equals(type)) { - includes.add(pattern); - } else if ("ex".equals(type) || "exclude".equals(type)) { - excludes.add(pattern); - } else if ("baseUrl".equals(type)) { - baseUrl = pattern; - } else { - System.err.println("Unkown bundles pattern type " + type); - } - } - - if (excludeSvn && !excludes.contains(EXCLUDES_SVN_PATTERN)) { - excludes.add(EXCLUDES_SVN_PATTERN); - } - } - - public String getDir() { - return dir; - } - - public List getIncludes() { - return includes; - } - - public List getExcludes() { - return excludes; - } - - public String getBaseUrl() { - return baseUrl; - } - - } } diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBootUtils.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBootUtils.java index da142cfe9..212e6baa4 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBootUtils.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBootUtils.java @@ -29,12 +29,16 @@ public class OsgiBootUtils { /** ISO8601 (as per log4j) and difference to UTC */ private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS Z"); + static boolean debug = Boolean.valueOf(System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_DEBUG, "false")) + .booleanValue(); + public static void info(Object obj) { System.out.println("# OSGiBOOT # " + dateFormat.format(new Date()) + " # " + obj); } public static void debug(Object obj) { - System.out.println("# OSGiBOOT DBG # " + dateFormat.format(new Date()) + " # " + obj); + if (debug) + System.out.println("# OSGiBOOT DBG # " + dateFormat.format(new Date()) + " # " + obj); } public static void warn(Object obj) { @@ -47,7 +51,6 @@ public class OsgiBootUtils { e.printStackTrace(); } - public static String stateAsString(int state) { switch (state) { case Bundle.UNINSTALLED: