From: Mathieu Baudier Date: Sat, 3 Feb 2018 20:44:28 +0000 (+0100) Subject: Scripting support X-Git-Tag: argeo-commons-2.1.71~32 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=5dc0e30ff215c1604b1b0e7bf8c8699f6cd1257f Scripting support --- diff --git a/demo/argeo_node.js b/demo/argeo_node.js new file mode 100755 index 000000000..4dc012b76 --- /dev/null +++ b/demo/argeo_node.js @@ -0,0 +1,16 @@ +#!/home/mbaudier/dev/git/apache2/argeo-commons/dist/osgi-boot/src/main/rpm/usr/bin/a2jjs + +// demo specific +var app = "node"; +var demoHome = $ENV.HOME + "/dev/git/apache2/argeo-commons/demo"; +var appHome = demoHome + "/exec/argeo_node.js"; +var appConf = demoHome; +var policyFile = "all.policy"; +load("../dist/argeo-node/rpm/usr/share/node/jjs/cms.js"); + +var distribution = "org.argeo.commons:org.argeo.dep.cms.platform:2.1.71-SNAPSHOT"; +osgi.install(distribution); +osgi.conf("org.osgi.service.http.port", "7070"); + +// osgi.conf("osgi.clean", true); +osgi.launch(); diff --git a/dist/argeo-node/pom.xml b/dist/argeo-node/pom.xml index da1c8cf5b..7d13069e5 100644 --- a/dist/argeo-node/pom.xml +++ b/dist/argeo-node/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 org.argeo.commons @@ -88,6 +89,21 @@ + + /usr/share/node/jjs + root + root + 644 + false + + + rpm/usr/share/node/jjs + + *.js + + + + /usr/sbin root diff --git a/dist/argeo-node/rpm/usr/share/node/jjs/cms.js b/dist/argeo-node/rpm/usr/share/node/jjs/cms.js new file mode 100755 index 000000000..b78fe0b5f --- /dev/null +++ b/dist/argeo-node/rpm/usr/share/node/jjs/cms.js @@ -0,0 +1,36 @@ +var System = Java.type("java.lang.System") +var OsgiBuilder = Java.type("org.argeo.osgi.boot.OsgiBuilder"); + +var osgi = new OsgiBuilder(); +osgi.start(2, "org.eclipse.equinox.http.servlet"); +osgi.start(2, "org.eclipse.equinox.http.jetty"); +osgi.start(2, "org.eclipse.equinox.metatype"); +osgi.start(2, "org.eclipse.equinox.cm"); +osgi.start(2, "org.eclipse.rap.rwt.osgi"); +osgi.start(3, "org.argeo.cms"); +osgi.start(4, "org.eclipse.gemini.blueprint.extender"); +osgi.start(4, "org.eclipse.equinox.http.registry"); +osgi.conf("org.eclipse.rap.workbenchAutostart", "false"); +osgi.conf("org.eclipse.equinox.http.jetty.autostart", "false"); +osgi.conf("org.osgi.framework.bootdelegation", "com.sun.jndi.ldap," + + "com.sun.jndi.ldap.sasl," + "com.sun.security.jgss," + + "com.sun.jndi.dns," + "com.sun.nio.file," + "com.sun.nio.sctp"); + +if (typeof app !== 'undefined') { + if (typeof appHome == 'undefined') { + var appHome = $ENV.HOME + "/.a2/var/lib/" + app; + } + if (typeof appConf == 'undefined') { + var appConf = $ENV.HOME + "/.a2/etc/" + app; + } + if (typeof policyFile == 'undefined') { + var policyFile = app + ".policy"; + } + osgi.conf("osgi.configuration.area", appHome + "/state"); + osgi.conf("osgi.instance.area", appHome + "/data"); + System.setProperty("java.security.manager", ""); + System.setProperty("java.security.policy", "file://" + appConf + "/" + + policyFile); + System.setProperty("log4j.configuration", "file://" + appConf + + "/log4j.properties"); +} \ No newline at end of file diff --git a/dist/osgi-boot/pom.xml b/dist/osgi-boot/pom.xml index 82b93b910..89fd1cff9 100644 --- a/dist/osgi-boot/pom.xml +++ b/dist/osgi-boot/pom.xml @@ -76,6 +76,21 @@ + + /usr/bin + root + root + 755 + false + + + src/main/rpm/usr/sbin + + * + + + + /usr/sbin root diff --git a/dist/osgi-boot/src/main/rpm/usr/bin/a2jjs b/dist/osgi-boot/src/main/rpm/usr/bin/a2jjs new file mode 100755 index 000000000..4ffab9f13 --- /dev/null +++ b/dist/osgi-boot/src/main/rpm/usr/bin/a2jjs @@ -0,0 +1,9 @@ +#!/bin/sh + +PREFIX=$HOME/.a2 +#PREFIX=/usr + +/usr/bin/jjs \ + -cp "$PREFIX/share/osgi/boot/org.eclipse.osgi.jar:$PREFIX/share/osgi/boot/org.argeo.osgi.boot.jar" \ + $* + diff --git a/org.argeo.osgi.boot/bnd.bnd b/org.argeo.osgi.boot/bnd.bnd index 9fb5d87be..f0fa329c8 100644 --- a/org.argeo.osgi.boot/bnd.bnd +++ b/org.argeo.osgi.boot/bnd.bnd @@ -1,4 +1,5 @@ Bundle-Activator: org.argeo.osgi.boot.Activator Import-Package: org.eclipse.*;resolution:=optional,\ +org.eclipse.osgi.launch.*;resolution:=optional,\ org.osgi.*;version=0.0.0,\ * 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 f8bee95de..bdf7134b8 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 @@ -67,9 +67,10 @@ public class OsgiBoot implements OsgiBootConstants { // 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"; + final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL = "osgi.bundles.defaultStartLevel"; + final static String PROP_OSGI_STARTLEVEL = "osgi.startLevel"; + final static String INSTANCE_AREA_PROP = "osgi.instance.area"; + final static String CONFIGURATION_AREA_PROP = "osgi.configuration.area"; // Symbolic names public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot"; @@ -277,7 +278,7 @@ public class OsgiBoot implements OsgiBootConstants { }); } - public static void computeStartLevels(SortedMap> startLevels, Properties properties, + private static void computeStartLevels(SortedMap> startLevels, Properties properties, Integer defaultStartLevel) { // default (and previously, only behaviour) @@ -431,12 +432,11 @@ public class OsgiBoot implements OsgiBootConstants { * BUNDLE PATTERNS INSTALLATION */ /** - * Computes a list of URLs based on Ant-like include/exclude patterns - * defined by ${argeo.osgi.bundles} with the following format:
+ * Computes a list of URLs based on Ant-like include/exclude patterns defined by + * ${argeo.osgi.bundles} with the following format:
* /base/directory;in=*.jar;in=**;ex=org.eclipse.osgi_*;jar
* WARNING: /base/directory;in=*.jar,\ at the end of a file, - * without a new line causes a '.' to be appended with unexpected side - * effects. + * without a new line causes a '.' to be appended with unexpected side effects. */ public List getBundlesUrls() { String bundlePatterns = getProperty(PROP_ARGEO_OSGI_BUNDLES); @@ -444,7 +444,7 @@ public class OsgiBoot implements OsgiBootConstants { } /** - * Compute alist of URLs to install based on the provided patterns, with + * Compute a list of URLs to install based on the provided patterns, with * default base url */ public List getBundlesUrls(String bundlePatterns) { @@ -453,7 +453,7 @@ public class OsgiBoot implements OsgiBootConstants { } /** Implements the path matching logic */ - List getBundlesUrls(String baseUrl, String bundlePatterns) { + public List getBundlesUrls(String baseUrl, String bundlePatterns) { List urls = new ArrayList(); if (bundlePatterns == null) return urls; @@ -519,15 +519,44 @@ public class OsgiBoot implements OsgiBootConstants { return urls; DistributionBundle distributionBundle; - if (baseUrl != null && !(distributionUrl.startsWith("http") || distributionUrl.startsWith("file"))) { - // relative url - distributionBundle = new DistributionBundle(baseUrl, distributionUrl, localCache); - } else { + if (distributionUrl.startsWith("http") || distributionUrl.startsWith("file")) { distributionBundle = new DistributionBundle(distributionUrl); if (baseUrl != null) distributionBundle.setBaseUrl(baseUrl); + } else { + // relative url + if (baseUrl == null) { + baseUrl = localCache; + } + if (distributionUrl.contains(":")) { + // TODO make it safer + String[] parts = distributionUrl.trim().split(":"); + String[] categoryParts = parts[0].split("\\."); + String artifactId = parts[1]; + String version = parts[2]; + StringBuilder sb = new StringBuilder(); + for (String categoryPart : categoryParts) { + sb.append(categoryPart).append('/'); + } + sb.append(artifactId).append('/'); + sb.append(version).append('/'); + sb.append(artifactId).append('-').append(version).append(".jar"); + distributionUrl = sb.toString(); + } + + distributionBundle = new DistributionBundle(baseUrl, distributionUrl, localCache); } + // if (baseUrl != null && !(distributionUrl.startsWith("http") || + // distributionUrl.startsWith("file"))) { + // // relative url + // distributionBundle = new DistributionBundle(baseUrl, distributionUrl, + // localCache); + // } else { + // distributionBundle = new DistributionBundle(distributionUrl); + // if (baseUrl != null) + // distributionBundle.setBaseUrl(baseUrl); + // } distributionBundle.processUrl(); return distributionBundle.listUrls(); } @@ -674,6 +703,10 @@ public class OsgiBoot implements OsgiBootConstants { return bundleContext; } + public String getLocalCache() { + return localCache; + } + // public void setDefaultTimeout(long defaultTimeout) { // this.defaultTimeout = defaultTimeout; // } 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 e21212662..455c96198 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,8 +29,8 @@ 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(); + static boolean debug = System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_DEBUG) == null ? false + : !System.getProperty(OsgiBoot.PROP_ARGEO_OSGI_BOOT_DEBUG).trim().equals("false"); public static void info(Object obj) { System.out.println("# OSGiBOOT # " + dateFormat.format(new Date()) + " # " + obj); @@ -51,6 +51,10 @@ public class OsgiBootUtils { e.printStackTrace(); } + public static boolean isDebug() { + return debug; + } + public static String stateAsString(int state) { switch (state) { case Bundle.UNINSTALLED: diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java new file mode 100644 index 000000000..7a8fd96bf --- /dev/null +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java @@ -0,0 +1,140 @@ +package org.argeo.osgi.boot; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeMap; + +import org.eclipse.osgi.launch.EquinoxFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.launch.Framework; +import org.osgi.framework.launch.FrameworkFactory; + +public class OsgiBuilder { + private Map startLevels = new TreeMap<>(); + private List distributionBundles = new ArrayList<>(); + + private Map configuration = new HashMap(); + private Framework framework; + + public OsgiBuilder() { + // configuration.put("osgi.clean", "true"); + configuration.put(OsgiBoot.CONFIGURATION_AREA_PROP, System.getProperty(OsgiBoot.CONFIGURATION_AREA_PROP)); + configuration.put(OsgiBoot.INSTANCE_AREA_PROP, System.getProperty(OsgiBoot.INSTANCE_AREA_PROP)); + } + + public Framework launch() { + // start OSGi + FrameworkFactory frameworkFactory = new EquinoxFactory(); + framework = frameworkFactory.newFramework(configuration); + try { + framework.start(); + } catch (BundleException e) { + throw new OsgiBootException("Cannot start OSGi framework", e); + } + + BundleContext bc = framework.getBundleContext(); + String osgiData = bc.getProperty(OsgiBoot.INSTANCE_AREA_PROP); + // String osgiConf = bc.getProperty(OsgiBoot.CONFIGURATION_AREA_PROP); + String osgiConf = framework.getDataFile("").getAbsolutePath(); + if (OsgiBootUtils.isDebug()) + OsgiBootUtils.debug("OSGi starting - data: " + osgiData + " conf: " + osgiConf); + + OsgiBoot osgiBoot = new OsgiBoot(framework.getBundleContext()); + // install bundles + for (String distributionBundle : distributionBundles) { + List bundleUrls = osgiBoot.getDistributionUrls(distributionBundle, null); + osgiBoot.installUrls(bundleUrls); + } + + // start bundles + osgiBoot.startBundles(startLevelsToProperties()); + + // if (OsgiBootUtils.isDebug()) + // for (Bundle bundle : bc.getBundles()) { + // OsgiBootUtils.debug(bundle.getLocation()); + // } + return framework; + } + + public OsgiBuilder conf(String key, String value) { + checkNotLaunched(); + configuration.put(key, value); + return this; + } + + public OsgiBuilder install(String uri) { + // TODO dynamic install + checkNotLaunched(); + if (!distributionBundles.contains(uri)) + distributionBundles.add(uri); + return this; + } + + public OsgiBuilder start(int startLevel, String bundle) { + // TODO dynamic start + checkNotLaunched(); + StartLevel sl; + if (!startLevels.containsKey(startLevel)) + startLevels.put(startLevel, new StartLevel()); + sl = startLevels.get(startLevel); + sl.add(bundle); + return this; + } + + public BundleContext getBc() { + checkLaunched(); + return framework.getBundleContext(); + } + + // + // UTILITIES + // + private Properties startLevelsToProperties() { + Properties properties = new Properties(); + for (Integer startLevel : startLevels.keySet()) { + String property = OsgiBoot.PROP_ARGEO_OSGI_START + "." + startLevel; + StringBuilder value = new StringBuilder(); + for (String bundle : startLevels.get(startLevel).getBundles()) { + value.append(bundle); + value.append(','); + } + // TODO remove trailing comma + properties.put(property, value.toString()); + } + return properties; + } + + private void checkLaunched() { + if (!isLaunched()) + throw new OsgiBootException("OSGi runtime is not launched"); + } + + private void checkNotLaunched() { + if (isLaunched()) + throw new OsgiBootException("OSGi runtime already launched"); + } + + private boolean isLaunched() { + return framework != null; + } + + private static class StartLevel { + private Set bundles = new HashSet<>(); + + public void add(String bundle) { + String[] b = bundle.split(","); + Collections.addAll(bundles, b); + } + + public Set getBundles() { + return bundles; + } + } +}