From 9c82ed02a7ee7b4a757853d8160587b27e493f1a Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 25 Jun 2009 12:38:48 +0000 Subject: [PATCH] Restructure OSGi launching git-svn-id: https://svn.argeo.org/slc/trunk@2574 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- demo/.classpath | 3 +- .../META-INF/spring/demo.xml | 2 + .../org.argeo.slc.demo.basic/conf/main.xml | 6 - .../org.argeo.slc.demo.basic/conf/osgi.xml | 3 +- .../org/argeo/slc/demo/StartStopDemoTest.java | 19 +- .../slc/demo/minimal/HelloWorldTest.java | 26 +++ demo/src/test/resources/log4j.properties | 16 ++ .../argeo/slc/execution/ExecutionModule.java | 6 +- .../execution/ExecutionModulesManager.java | 13 +- .../main/java/org/argeo/slc/jms/JmsAgent.java | 17 +- .../slc/equinox/ExecutionCommandProvider.java | 99 +-------- .../org/argeo/slc/osgi/BundlesManager.java | 143 ++++++++++--- .../MultipleServiceExporterPostProcessor.java | 59 +++++ .../java/org/argeo/slc/osgi/OsgiBundle.java | 31 ++- .../argeo/slc/osgi/OsgiExecutionLauncher.java | 155 -------------- .../argeo/slc/osgi/OsgiExecutionModule.java | 82 +++++-- .../slc/osgi/OsgiExecutionModulesManager.java | 201 ++++++++++++++++++ .../argeo/slc/osgi/OsgiModulesManager.java | 24 --- .../resources/META-INF/spring/manager.xml | 7 +- .../main/resources/META-INF/spring/osgi.xml | 2 +- .../org/argeo/slc/osgi/execution/spring.xml | 20 ++ ...a => AbstractExecutionModulesManager.java} | 149 ++++++++----- .../AbstractSpringExecutionModule.java | 29 +-- .../core/execution/DefaultExecutionFlow.java | 10 +- .../slc/core/execution/ExecutionScope.java | 10 +- .../core/execution/ResourceSpecAttribute.java | 59 ----- .../execution/DefaultModulesManagerTest.java | 6 +- .../slc/core/execution/ResourceTest.java | 17 -- .../argeo/slc/core/execution/resourceTest.xml | 40 ---- .../META-INF/spring/manager.xml | 7 +- .../META-INF/spring/osgi.xml | 4 - server/org.argeo.slc.siteserver/pom.xml | 4 +- 32 files changed, 709 insertions(+), 560 deletions(-) create mode 100644 demo/src/test/java/org/argeo/slc/demo/minimal/HelloWorldTest.java create mode 100644 demo/src/test/resources/log4j.properties create mode 100644 runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java delete mode 100644 runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionLauncher.java create mode 100644 runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java delete mode 100644 runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiModulesManager.java create mode 100644 runtime/org.argeo.slc.support.equinox/src/main/resources/org/argeo/slc/osgi/execution/spring.xml rename runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/{DefaultModulesManager.java => AbstractExecutionModulesManager.java} (57%) delete mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java delete mode 100644 runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/ResourceTest.java delete mode 100644 runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/resourceTest.xml diff --git a/demo/.classpath b/demo/.classpath index 624a6cfe1..8fa9377c2 100644 --- a/demo/.classpath +++ b/demo/.classpath @@ -1,6 +1,7 @@ - + + diff --git a/demo/site/org.argeo.slc.demo.agent/META-INF/spring/demo.xml b/demo/site/org.argeo.slc.demo.agent/META-INF/spring/demo.xml index ae43462c9..c4fa68123 100644 --- a/demo/site/org.argeo.slc.demo.agent/META-INF/spring/demo.xml +++ b/demo/site/org.argeo.slc.demo.agent/META-INF/spring/demo.xml @@ -8,4 +8,6 @@ + \ No newline at end of file diff --git a/demo/site/org.argeo.slc.demo.basic/conf/main.xml b/demo/site/org.argeo.slc.demo.basic/conf/main.xml index 062a7aaf1..640eb5aaa 100644 --- a/demo/site/org.argeo.slc.demo.basic/conf/main.xml +++ b/demo/site/org.argeo.slc.demo.basic/conf/main.xml @@ -7,12 +7,6 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> - - - - - - diff --git a/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml b/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml index a759f5b5c..a6f9740ef 100644 --- a/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml +++ b/demo/site/org.argeo.slc.demo.basic/conf/osgi.xml @@ -6,8 +6,7 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + diff --git a/demo/src/test/java/org/argeo/slc/demo/StartStopDemoTest.java b/demo/src/test/java/org/argeo/slc/demo/StartStopDemoTest.java index b8562241f..3feba8e59 100644 --- a/demo/src/test/java/org/argeo/slc/demo/StartStopDemoTest.java +++ b/demo/src/test/java/org/argeo/slc/demo/StartStopDemoTest.java @@ -1,23 +1,28 @@ package org.argeo.slc.demo; +import java.util.ArrayList; +import java.util.List; + +import org.argeo.slc.equinox.unit.AbstractOsgiRuntimeTestCase; +import org.argeo.slc.osgiboot.OsgiBoot; + +public class StartStopDemoTest extends AbstractOsgiRuntimeTestCase { -public class StartStopDemoTest {//extends AbstractOsgiRuntimeTestCase { - /* public void testStartStop() throws Exception { assertBundleApplicationContext("org.argeo.slc.agent"); assertStartedBundlesApplicationContext("org.argeo.slc.demo"); } protected void installBundles() throws Exception { - osgiBoot.installUrls(osgiBoot.getBundlesUrls(OsgiBoot.DEFAULT_BASE_URL, - "target/dependency;in=*.jar")); + // osgiBoot.installUrls(osgiBoot.getBundlesUrls(OsgiBoot.DEFAULT_BASE_URL, + // "target/dependency;in=*.jar")); osgiBoot.installUrls(osgiBoot.getLocationsUrls( OsgiBoot.DEFAULT_BASE_URL, System .getProperty("java.class.path"))); osgiBoot.installUrls(osgiBoot.getBundlesUrls(OsgiBoot.DEFAULT_BASE_URL, "site;in=*")); -// osgiBoot.installUrls(osgiBoot.getBundlesUrls(OsgiBoot.DEFAULT_BASE_URL, -// "../server/org.argeo.slc.siteserver/bundles;in=*")); + osgiBoot.installUrls(osgiBoot.getBundlesUrls(OsgiBoot.DEFAULT_BASE_URL, + "../server/org.argeo.slc.siteserver/bundles;in=*")); } protected List getBundlesToStart() { @@ -27,5 +32,5 @@ public class StartStopDemoTest {//extends AbstractOsgiRuntimeTestCase { bundlesToStart.add("org.argeo.slc.demo.basic"); return bundlesToStart; } -*/ + } diff --git a/demo/src/test/java/org/argeo/slc/demo/minimal/HelloWorldTest.java b/demo/src/test/java/org/argeo/slc/demo/minimal/HelloWorldTest.java new file mode 100644 index 000000000..bcb41ebd0 --- /dev/null +++ b/demo/src/test/java/org/argeo/slc/demo/minimal/HelloWorldTest.java @@ -0,0 +1,26 @@ +package org.argeo.slc.demo.minimal; + +import junit.framework.TestCase; + +import org.argeo.slc.execution.ExecutionFlow; +import org.springframework.beans.factory.generic.GenericBeanFactoryAccessor; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.FileSystemXmlApplicationContext; + +public class HelloWorldTest extends TestCase { + public void testHelloWorld() throws Exception { + GenericBeanFactoryAccessor context = new GenericBeanFactoryAccessor( + createContext()); + ExecutionFlow flow = context.getBean("main"); + flow.run(); + } + + protected ConfigurableApplicationContext createContext() { + String[] locations = { "site/org.argeo.slc.demo.groovy/slc/main.xml", + "site/org.argeo.slc.demo.groovy/slc/imports.xml" }; + FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext( + locations); + return context; + } + +} diff --git a/demo/src/test/resources/log4j.properties b/demo/src/test/resources/log4j.properties new file mode 100644 index 000000000..9572fad6c --- /dev/null +++ b/demo/src/test/resources/log4j.properties @@ -0,0 +1,16 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=WARN, console + +## Levels +# Slc +log4j.logger.org.argeo.slc=DEBUG +log4j.logger.org.springframework=WARN + +## Appenders +# A1 is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c %n + diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModule.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModule.java index b8979897f..11021f60e 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModule.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModule.java @@ -1,12 +1,12 @@ package org.argeo.slc.execution; - +@Deprecated public interface ExecutionModule { - public String getName(); +/* public String getName(); public String getVersion(); public ExecutionModuleDescriptor getDescriptor(); - public void execute(ExecutionFlowDescriptor descriptor); + public void execute(ExecutionFlowDescriptor descriptor);*/ } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java index 329145be8..66ddc9cf4 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionModulesManager.java @@ -2,13 +2,24 @@ package org.argeo.slc.execution; import java.util.List; +import org.argeo.slc.process.RealizedFlow; import org.argeo.slc.process.SlcExecution; +/** Provides access to the execution modules */ public interface ExecutionModulesManager { + /** @return a full fledged module descriptor. */ public ExecutionModuleDescriptor getExecutionModuleDescriptor( String moduleName, String version); - public List listExecutionModules(); + /** + * @return a list of minimal execution module descriptors (only the module + * meta data, not the flows) + */ + public List listExecutionModules(); + /** Asynchronously prepare and executes an {@link SlcExecution} */ public void process(SlcExecution slcExecution); + + /** Synchronously finds and executes an {@link ExecutionFlow}. */ + public void execute(RealizedFlow realizedFlow); } diff --git a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAgent.java b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAgent.java index d264042f9..47e218301 100644 --- a/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAgent.java +++ b/runtime/org.argeo.slc.support.activemq/src/main/java/org/argeo/slc/jms/JmsAgent.java @@ -2,7 +2,6 @@ package org.argeo.slc.jms; import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -15,7 +14,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; import org.argeo.slc.core.runtime.AbstractAgent; -import org.argeo.slc.execution.ExecutionModule; import org.argeo.slc.execution.ExecutionModuleDescriptor; import org.argeo.slc.msg.ExecutionAnswer; import org.argeo.slc.msg.MsgConstants; @@ -107,17 +105,7 @@ public class JmsAgent extends AbstractAgent implements SlcAgent, } public List listExecutionModuleDescriptors() { - List modules = getModulesManager() - .listExecutionModules(); - - List descriptors = new ArrayList(); - for (ExecutionModule module : modules) { - ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); - md.setName(module.getName()); - md.setVersion(module.getVersion()); - descriptors.add(md); - } - return descriptors; + return getModulesManager().listExecutionModules(); } public boolean ping() { @@ -158,7 +146,8 @@ public class JmsAgent extends AbstractAgent implements SlcAgent, public Message postProcessMessage(Message messageToSend) throws JMSException { messageToSend.setStringProperty(PROPERTY_QUERY, query); - messageToSend.setStringProperty(MsgConstants.PROPERTY_SLC_AGENT_ID, + messageToSend.setStringProperty( + MsgConstants.PROPERTY_SLC_AGENT_ID, agentDescriptor.getUuid()); messageToSend.setJMSCorrelationID(correlationId); return messageToSend; diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/equinox/ExecutionCommandProvider.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/equinox/ExecutionCommandProvider.java index 3c6912b21..56bcc3c4f 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/equinox/ExecutionCommandProvider.java +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/equinox/ExecutionCommandProvider.java @@ -3,41 +3,21 @@ package org.argeo.slc.equinox; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; -import org.argeo.slc.execution.ExecutionFlowDescriptor; -import org.argeo.slc.execution.ExecutionModule; -import org.argeo.slc.osgi.BundlesManager; -import org.argeo.slc.osgi.OsgiExecutionLauncher; +import org.argeo.slc.osgi.OsgiExecutionModulesManager; +import org.argeo.slc.process.RealizedFlow; import org.eclipse.core.runtime.adaptor.EclipseStarter; -import org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher; import org.eclipse.osgi.framework.console.CommandInterpreter; import org.eclipse.osgi.framework.console.CommandProvider; -import org.eclipse.osgi.framework.launcher.Launcher; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationContext; -import org.springframework.osgi.context.BundleContextAware; public class ExecutionCommandProvider implements CommandProvider, InitializingBean { private final static Log log = LogFactory .getLog(ExecutionCommandProvider.class); - // private BundleContext bundleContext; - // private BundlesManager bundlesManager; + private OsgiExecutionModulesManager modulesManager; - private OsgiExecutionLauncher executionLauncher; - - private OsgiExecutionLauncher.Launch lastLaunch = null; - - // private String lastModuleName = null; - // private String lastExecutionName = null; - - /** @deprecated Use slc command instead. */ - public Object _slc_exec(CommandInterpreter ci) { - return _slc(ci); - } + private RealizedFlow lastLaunch = null; public Object _slc(CommandInterpreter ci) { // TODO: check version @@ -45,7 +25,7 @@ public class ExecutionCommandProvider implements CommandProvider, if (firstArg == null) { if (lastLaunch != null) { String cmd = "slc " + lastLaunch.getModuleName() + " " - + lastLaunch.getExecutionName(); + + lastLaunch.getFlowDescriptor().getName(); if (log.isDebugEnabled()) log.debug("Execute again last command: " + cmd); return ci.execute(cmd); @@ -57,68 +37,16 @@ public class ExecutionCommandProvider implements CommandProvider, String executionName = ci.nextArgument(); launch(firstArg, executionName); - /* - * String moduleName = null; - * - * // First check whether we have a bundleId Long bundleId = null; try { - * bundleId = Long.parseLong(firstArg); } catch (NumberFormatException - * e) { // silent } - * - * // Look for bundle names containing pattern Bundle bundle = null; if - * (bundleId != null) { bundle = bundleContext.getBundle(bundleId); } - * else { for (Bundle b : bundleContext.getBundles()) { if - * (b.getSymbolicName().contains(firstArg)) { bundle = b; break; } } } - * - * if (bundle != null) { moduleName = bundle.getSymbolicName(); - * lastModuleName = moduleName; lastExecutionName = executionName; } - * else { log - * .warn("Could not find any execution module matching these requirements." - * ); return null; } - * - * // Find module ExecutionModule module = null; ServiceReference - * serviceRef = null; try { bundlesManager.stopSynchronous(bundle); - * bundlesManager.updateSynchronous(bundle); // Refresh in case there - * are fragments bundlesManager.refreshSynchronous(bundle); - * bundlesManager.startSynchronous(bundle); - * - * String filter = "(Bundle-SymbolicName=" + moduleName + ")"; // Wait - * for application context to be ready - * bundlesManager.getServiceRefSynchronous(ApplicationContext.class - * .getName(), filter); - * - * if (log.isDebugEnabled()) log.debug("Bundle " + - * bundle.getSymbolicName() + " ready to be used at latest version."); - * - * ServiceReference[] sfs = bundlesManager.getServiceRefSynchronous( - * ExecutionModule.class.getName(), filter); - * - * if (sfs.length > 1) log - * .warn("More than one execution module service found in module " + - * moduleName); - * - * if (sfs.length > 0) { serviceRef = sfs[0]; module = (ExecutionModule) - * bundleContext.getService(serviceRef); } - * - * if (module != null) { ExecutionFlowDescriptor descriptor = new - * ExecutionFlowDescriptor(); descriptor.setName(executionName); - * module.execute(descriptor); log.info("Executed " + executionName + - * " from " + moduleName); } - * - * } catch (Exception e) { throw new - * SlcException("Cannot find or update module.", e); } finally { if - * (serviceRef != null) bundleContext.ungetService(serviceRef); } - */ - return "COMMAND COMPLETED"; } protected void launch(String firstArg, String executionName) { - lastLaunch = executionLauncher.findLaunch(firstArg, executionName); + lastLaunch = modulesManager.findRealizedFlow(firstArg, executionName); if (lastLaunch == null) throw new SlcException("Cannot find launch for " + firstArg + " " + executionName); - executionLauncher.launch(lastLaunch); + modulesManager.updateAndExecute(lastLaunch); } @@ -131,8 +59,8 @@ public class ExecutionCommandProvider implements CommandProvider, } - public void setExecutionLauncher(OsgiExecutionLauncher launcher) { - this.executionLauncher = launcher; + public void setModulesManager(OsgiExecutionModulesManager osgiModulesManager) { + this.modulesManager = osgiModulesManager; } public void afterPropertiesSet() throws Exception { @@ -162,13 +90,4 @@ public class ExecutionCommandProvider implements CommandProvider, } } - - // public void setBundleContext(BundleContext bundleContext) { - // this.bundleContext = bundleContext; - // } - - // public void setBundlesManager(BundlesManager bundlesManager) { - // this.bundlesManager = bundlesManager; - // } - } diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java index 7eb6d0b88..6d1c79faf 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/BundlesManager.java @@ -1,24 +1,25 @@ package org.argeo.slc.osgi; -import java.util.ArrayList; -import java.util.List; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkListener; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.PackageAdmin; +import org.osgi.util.tracker.ServiceTracker; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.osgi.context.BundleContextAware; +import org.springframework.osgi.util.OsgiFilterUtils; +import org.springframework.util.Assert; -/** Wraps access to a {@link BundleContext} */ +/** Wraps low-level access to a {@link BundleContext} */ public class BundlesManager implements BundleContextAware, FrameworkListener, InitializingBean { private final static Log log = LogFactory.getLog(BundlesManager.class); @@ -28,8 +29,34 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, private Long defaultTimeout = 10000l; private final Object refreshedPackageSem = new Object(); + /** + * Stop the module, update it, refresh it and restart it. All synchronously. + */ + public void upgradeSynchronous(OsgiBundle osgiBundle) { + try { + Bundle bundle = findRelatedBundle(osgiBundle); + stopSynchronous(bundle); + updateSynchronous(bundle); + // Refresh in case there are fragments + refreshSynchronous(bundle); + startSynchronous(bundle); + + String filter = "(Bundle-SymbolicName=" + bundle.getSymbolicName() + + ")"; + // Wait for application context to be ready + // TODO: use service tracker + getServiceRefSynchronous(ApplicationContext.class.getName(), filter); + + if (log.isDebugEnabled()) + log.debug("Bundle " + bundle.getSymbolicName() + + " ready to be used at latest version."); + } catch (Exception e) { + throw new SlcException("Cannot update bundle " + osgiBundle, e); + } + } + /** Updates bundle synchronously. */ - public void updateSynchronous(Bundle bundle) throws BundleException { + protected void updateSynchronous(Bundle bundle) throws BundleException { // int originalState = bundle.getState(); bundle.update(); boolean waiting = true; @@ -53,7 +80,7 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, } /** Starts bundle synchronously. Does nothing if already started. */ - public void startSynchronous(Bundle bundle) throws BundleException { + protected void startSynchronous(Bundle bundle) throws BundleException { int originalState = bundle.getState(); if (originalState == Bundle.ACTIVE) return; @@ -78,7 +105,7 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, } /** Stops bundle synchronously. Does nothing if already started. */ - public void stopSynchronous(Bundle bundle) throws BundleException { + protected void stopSynchronous(Bundle bundle) throws BundleException { int originalState = bundle.getState(); if (originalState != Bundle.ACTIVE) return; @@ -104,7 +131,7 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, } /** Refresh bundle synchronously. Does nothing if already started. */ - public void refreshSynchronous(Bundle bundle) throws BundleException { + protected void refreshSynchronous(Bundle bundle) throws BundleException { ServiceReference packageAdminRef = bundleContext .getServiceReference(PackageAdmin.class.getName()); PackageAdmin packageAdmin = (PackageAdmin) bundleContext @@ -132,24 +159,6 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, } } - public List listPublishedApplicationContexts( - String filter) { - try { - List lst = new ArrayList(); - ServiceReference[] sfs = bundleContext.getServiceReferences( - ApplicationContext.class.getName(), filter); - for (int i = 0; i < sfs.length; i++) { - ApplicationContext applicationContext = (ApplicationContext) bundleContext - .getService(sfs[i]); - lst.add(applicationContext); - } - return lst; - } catch (InvalidSyntaxException e) { - throw new SlcException( - "Cannot list published application contexts", e); - } - } - public ServiceReference[] getServiceRefSynchronous(String clss, String filter) throws InvalidSyntaxException { if (log.isTraceEnabled()) @@ -180,6 +189,83 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, } } + /** Creates and open a new service tracker. */ + public ServiceTracker newTracker(Class clss) { + ServiceTracker st = new ServiceTracker(bundleContext, clss.getName(), + null); + st.open(); + return st; + } + + @SuppressWarnings(value = { "unchecked" }) + public T getSingleService(Class clss, String filter) { + Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter"); + ServiceReference[] sfs; + try { + sfs = bundleContext.getServiceReferences(clss.getName(), filter); + } catch (InvalidSyntaxException e) { + throw new SlcException("Cannot retrieve service reference for " + + filter, e); + } + + if (sfs == null || sfs.length == 0) + return null; + else if (sfs.length > 1) + throw new SlcException("More than one execution flow found for " + + filter); + return (T) bundleContext.getService(sfs[0]); + } + + public T getSingleServiceStrict(Class clss, String filter) { + T service = getSingleService(clss, filter); + if (service == null) + throw new SlcException("No execution flow found for " + filter); + else + return service; + } + + /** @return the related bundle or null if not found */ + public Bundle findRelatedBundle(OsgiBundle osgiBundle) { + Bundle bundle = null; + if (osgiBundle.getInternalBundleId() != null) { + bundle = bundleContext.getBundle(osgiBundle.getInternalBundleId()); + Assert.isTrue( + osgiBundle.getName().equals(bundle.getSymbolicName()), + "symbolic name consistent"); + Assert.isTrue(osgiBundle.getVersion().equals( + bundle.getHeaders().get(Constants.BUNDLE_VERSION)), + "version consistent"); + } else { + for (Bundle b : bundleContext.getBundles()) { + if (b.getSymbolicName().equals(osgiBundle.getName())) { + if (b.getHeaders().get(Constants.BUNDLE_VERSION).equals( + osgiBundle.getVersion())) { + bundle = b; + osgiBundle.setInternalBundleId(b.getBundleId()); + } + } + } + } + return bundle; + } + + /** Find a single bundle based on a symbolic name pattern. */ + public OsgiBundle findFromPattern(String pattern) { + OsgiBundle osgiBundle = null; + for (Bundle b : bundleContext.getBundles()) { + if (b.getSymbolicName().contains(pattern)) { + osgiBundle = new OsgiBundle(b); + break; + } + } + return osgiBundle; + } + + public OsgiBundle getBundle(Long bundleId) { + Bundle bundle = bundleContext.getBundle(bundleId); + return new OsgiBundle(bundle); + } + public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } @@ -192,4 +278,9 @@ public class BundlesManager implements BundleContextAware, FrameworkListener, this.defaultTimeout = defaultTimeout; } + /** Temporary internal access for {@link OsgiExecutionModulesManager} */ + BundleContext getBundleContext() { + return bundleContext; + } + } diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java new file mode 100644 index 000000000..b9e39f86c --- /dev/null +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/MultipleServiceExporterPostProcessor.java @@ -0,0 +1,59 @@ +package org.argeo.slc.osgi; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.argeo.slc.SlcException; +import org.springframework.beans.BeansException; +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean; + +@SuppressWarnings(value = { "unchecked" }) +public class MultipleServiceExporterPostProcessor implements + BeanFactoryPostProcessor { + private List interfaces = new ArrayList(); + + private Class osgiServiceFactoryClass = OsgiServiceFactoryBean.class; + + public void postProcessBeanFactory( + ConfigurableListableBeanFactory beanFactory) throws BeansException { + if (!(beanFactory instanceof BeanDefinitionRegistry)) { + throw new SlcException("Can only work on " + + BeanDefinitionRegistry.class); + } + + // Merge all beans implementing these interfaces + Set beanNames = new HashSet(); + for (Class clss : interfaces) { + String[] strs = beanFactory.getBeanNamesForType(clss, true, false); + beanNames.addAll(Arrays.asList(strs)); + } + + // Register service factory beans for them + for (String beanName : beanNames) { + MutablePropertyValues mpv = new MutablePropertyValues(); + mpv.addPropertyValue("interfaces", interfaces.toArray()); + mpv.addPropertyValue("targetBeanName", beanName); + RootBeanDefinition bd = new RootBeanDefinition( + osgiServiceFactoryClass, mpv); + ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition( + "osgiService." + beanName, bd); + } + } + + public void setInterfaces(List interfaces) { + this.interfaces = interfaces; + } + + public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) { + this.osgiServiceFactoryClass = osgiServiceFactoryClass; + } + +} diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiBundle.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiBundle.java index 47ca2ea72..45cee40e2 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiBundle.java +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiBundle.java @@ -5,20 +5,30 @@ import org.argeo.slc.core.deploy.ResourceDistribution; import org.argeo.slc.deploy.DeploymentData; import org.argeo.slc.deploy.Module; import org.argeo.slc.deploy.TargetData; +import org.argeo.slc.process.RealizedFlow; import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; public class OsgiBundle implements Module { private String name; private String version; private Distribution distribution; + private Long internalBundleId; + public OsgiBundle() { } public OsgiBundle(Bundle bundle) { name = bundle.getSymbolicName(); - version = bundle.getHeaders().get("Bundle-Version").toString(); + version = bundle.getHeaders().get(Constants.BUNDLE_VERSION).toString(); + internalBundleId = bundle.getBundleId(); + } + + public OsgiBundle(RealizedFlow realizedFlow) { + name = realizedFlow.getModuleName(); + version = realizedFlow.getModuleVersion(); } public String getDeployedSystemId() { @@ -26,8 +36,7 @@ public class OsgiBundle implements Module { } public DeploymentData getDeploymentData() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException(); } public Distribution getDistribution() { @@ -35,8 +44,7 @@ public class OsgiBundle implements Module { } public TargetData getTargetData() { - // TODO Auto-generated method stub - return null; + throw new UnsupportedOperationException(); } public String getName() { @@ -59,4 +67,17 @@ public class OsgiBundle implements Module { this.distribution = distribution; } + /** + * To be used for optimization when looking in the bundle context. Can + * therefore be null. + */ + public Long getInternalBundleId() { + return internalBundleId; + } + + /** Only package access for the time being. e.g. from {@link BundlesManager} */ + void setInternalBundleId(Long internalBundleId) { + this.internalBundleId = internalBundleId; + } + } diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionLauncher.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionLauncher.java deleted file mode 100644 index 1b911269b..000000000 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionLauncher.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.argeo.slc.osgi; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.slc.SlcException; -import org.argeo.slc.execution.ExecutionFlowDescriptor; -import org.argeo.slc.execution.ExecutionModule; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.springframework.context.ApplicationContext; -import org.springframework.osgi.context.BundleContextAware; - -public class OsgiExecutionLauncher implements BundleContextAware { - private final static Log log = LogFactory - .getLog(OsgiExecutionLauncher.class); - - private BundleContext bundleContext; - private BundlesManager bundlesManager; - - public Launch findLaunch(String firstArg, String executionName) { - Launch launch = new Launch(); - - // String moduleName = null; - - // First check whether we have a bundleId - Long bundleId = null; - try { - bundleId = Long.parseLong(firstArg); - } catch (NumberFormatException e) { - // silent - } - - // Look for bundle names containing pattern - Bundle bundle = null; - if (bundleId != null) { - bundle = bundleContext.getBundle(bundleId); - } else { - for (Bundle b : bundleContext.getBundles()) { - if (b.getSymbolicName().contains(firstArg)) { - bundle = b; - break; - } - } - } - - if (bundle != null) { - launch.setBundleId(bundle.getBundleId()); - launch.setModuleName(bundle.getSymbolicName()); - launch.setExecutionName(executionName); - return launch; - } else { - log - .warn("Could not find any execution module matching these requirements."); - return null; - } - - } - - public void launch(Launch launch) { - Bundle bundle = bundleContext.getBundle(launch.getBundleId()); - - // Find module - ExecutionModule module = null; - ServiceReference serviceRef = null; - try { - bundlesManager.stopSynchronous(bundle); - bundlesManager.updateSynchronous(bundle); - // Refresh in case there are fragments - bundlesManager.refreshSynchronous(bundle); - bundlesManager.startSynchronous(bundle); - - String filter = "(Bundle-SymbolicName=" + launch.getModuleName() - + ")"; - // Wait for application context to be ready - bundlesManager.getServiceRefSynchronous(ApplicationContext.class - .getName(), filter); - - if (log.isDebugEnabled()) - log.debug("Bundle " + bundle.getSymbolicName() - + " ready to be used at latest version."); - - ServiceReference[] sfs = bundlesManager.getServiceRefSynchronous( - ExecutionModule.class.getName(), filter); - - if (sfs.length > 1) - log - .warn("More than one execution module service found in module " - + launch.getModuleName()); - - if (sfs.length > 0) { - serviceRef = sfs[0]; - module = (ExecutionModule) bundleContext.getService(serviceRef); - } - - if (module != null) { - ExecutionFlowDescriptor descriptor = new ExecutionFlowDescriptor(); - descriptor.setName(launch.getExecutionName()); - module.execute(descriptor); - log.info("Executed " + launch.getExecutionName() + " from " - + launch.getModuleName()); - } - - } catch (Exception e) { - throw new SlcException("Cannot launch " + launch, e); - } finally { - if (serviceRef != null) - bundleContext.ungetService(serviceRef); - } - } - - public void setBundleContext(BundleContext bundleContext) { - this.bundleContext = bundleContext; - } - - public void setBundlesManager(BundlesManager bundlesManager) { - this.bundlesManager = bundlesManager; - } - - public static class Launch { - private Long bundleId; - private String moduleName; - private String executionName; - - public Long getBundleId() { - return bundleId; - } - - public void setBundleId(Long bundleId) { - this.bundleId = bundleId; - } - - public String getModuleName() { - return moduleName; - } - - public void setModuleName(String moduleName) { - this.moduleName = moduleName; - } - - public String getExecutionName() { - return executionName; - } - - public void setExecutionName(String executionName) { - this.executionName = executionName; - } - - @Override - public String toString() { - return moduleName + " " + executionName; - } - - } -} diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModule.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModule.java index 1708240e9..ca3f5faa7 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModule.java +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModule.java @@ -1,24 +1,80 @@ package org.argeo.slc.osgi; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.slc.core.execution.AbstractSpringExecutionModule; -import org.osgi.framework.BundleContext; -import org.springframework.osgi.context.BundleContextAware; +import org.argeo.slc.execution.ExecutionContext; -public class OsgiExecutionModule extends AbstractSpringExecutionModule implements - BundleContextAware { - private BundleContext bundleContext; +@Deprecated +public class OsgiExecutionModule extends AbstractSpringExecutionModule { + private final static Log log = LogFactory.getLog(OsgiExecutionModule.class); - public String getName() { - return bundleContext.getBundle().getSymbolicName(); + public OsgiExecutionModule() { + log.error("######## ERROR - DEPRECATED APPROACH USED ########"); + log.error(OsgiExecutionModule.class.getName() + " is deprecated. "); + log + .error("It will be removed in the next release. Remove its bean definition."); + log + .error("And replace: "); + log + .error("by: "); + log.error("in osgi.xml.\n\n"); } - public String getVersion() { - return bundleContext.getBundle().getHeaders().get("Bundle-Version") - .toString(); + public void setExecutionContext(ExecutionContext executionContext) { + // do nothing, just for compatibility } - public void setBundleContext(BundleContext bundleContext) { - this.bundleContext = bundleContext; - } + /* + * private BundleContext bundleContext; + * + * @Override public void execute(ExecutionFlowDescriptor + * executionFlowDescriptor) { if (descriptorConverter != null) + * executionContext.addVariables(descriptorConverter + * .convertValues(executionFlowDescriptor)); + * + * ExecutionFlow flow = findExecutionFlow(getName(), getVersion(), + * executionFlowDescriptor.getName()); flow.run(); } + * + * @Override protected Map listFlows() { String + * filter = "(org.argeo.slc.execution.module.name=" + getName() + ")"; + * ServiceReference[] sfs; try { sfs = + * bundleContext.getServiceReferences(ExecutionFlow.class .getName(), + * filter); } catch (InvalidSyntaxException e) { throw new SlcException( + * "Cannot retrieve service reference for flow " + filter, e); } + * + * Map flows = new HashMap(); + * for (ServiceReference sf : sfs) { ExecutionFlow flow = (ExecutionFlow) + * bundleContext.getService(sf); flows.put(flow.getName(), flow); } return + * flows; } + * + * public String getName() { return + * bundleContext.getBundle().getSymbolicName(); } + * + * public String getVersion() { return + * bundleContext.getBundle().getHeaders().get("Bundle-Version") .toString(); + * } + * + * public void setBundleContext(BundleContext bundleContext) { + * this.bundleContext = bundleContext; } + * + * protected ExecutionFlow findExecutionFlow(String moduleName, String + * moduleVersion, String flowName) { String filter = + * "(&(org.argeo.slc.execution.module.name=" + moduleName + + * ")(org.argeo.slc.execution.flow.name=" + flowName + "))"; + * log.debug("OSGi filter: " + filter); + * + * Assert.isTrue(OsgiFilterUtils.isValidFilter(filter), "valid filter"); + * ServiceReference[] sfs; try { sfs = + * bundleContext.getServiceReferences(ExecutionFlow.class .getName(), + * filter); } catch (InvalidSyntaxException e) { throw new + * SlcException("Cannot retrieve service reference for " + filter, e); } + * + * if (sfs == null || sfs.length == 0) throw new + * SlcException("No execution flow found for " + filter); else if + * (sfs.length > 1) throw new + * SlcException("More than one execution flow found for " + filter); return + * (ExecutionFlow) bundleContext.getService(sfs[0]); } + */ } diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java new file mode 100644 index 000000000..1dde56029 --- /dev/null +++ b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java @@ -0,0 +1,201 @@ +package org.argeo.slc.osgi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.SlcException; +import org.argeo.slc.core.execution.AbstractExecutionModulesManager; +import org.argeo.slc.core.execution.DefaultDescriptorConverter; +import org.argeo.slc.execution.ExecutionContext; +import org.argeo.slc.execution.ExecutionFlow; +import org.argeo.slc.execution.ExecutionFlowDescriptor; +import org.argeo.slc.execution.ExecutionFlowDescriptorConverter; +import org.argeo.slc.execution.ExecutionModuleDescriptor; +import org.argeo.slc.process.RealizedFlow; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +public class OsgiExecutionModulesManager extends AbstractExecutionModulesManager implements + InitializingBean, DisposableBean { + private final static Log log = LogFactory.getLog(OsgiExecutionModulesManager.class); + + private BundlesManager bundlesManager; + private ServiceTracker executionContexts; + private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultDescriptorConverter(); + + public ExecutionModuleDescriptor getExecutionModuleDescriptor( + String moduleName, String version) { + return createDescriptor(moduleName, version, listFlows(moduleName, + version)); + } + + public List listExecutionModules() { + List descriptors = new ArrayList(); + + ServiceReference[] srs = executionContexts.getServiceReferences(); + for (ServiceReference sr : srs) { + String moduleName = sr.getBundle().getSymbolicName(); + String moduleVersion = sr.getBundle().getHeaders().get( + "Bundle-Version").toString(); + ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); + md.setName(moduleName); + md.setVersion(moduleVersion); + descriptors.add(md); + } + return descriptors; + } + + protected Map listFlows(String moduleName, + String moduleVersion) { + // TODO: use service trackers? + // String filter = OsgiFilterUtils.unifyFilter(ExecutionFlow.class, + // null); + + String filter = "(Bundle-SymbolicName=" + moduleName + ")"; + ServiceReference[] sfs; + try { + sfs = bundlesManager.getBundleContext().getServiceReferences( + ExecutionFlow.class.getName(), filter); + } catch (InvalidSyntaxException e) { + throw new SlcException( + "Cannot retrieve service reference for flow " + filter, e); + } + + Map flows = new HashMap(); + for (ServiceReference sf : sfs) { + ExecutionFlow flow = (ExecutionFlow) bundlesManager + .getBundleContext().getService(sf); + flows.put(flow.getName(), flow); + } + return flows; + } + + public ExecutionFlow findExecutionFlow(String moduleName, + String moduleVersion, String flowName) { + String filter = "(&(Bundle-SymbolicName=" + moduleName + + ")(org.springframework.osgi.bean.name=" + flowName + "))"; + return bundlesManager.getSingleServiceStrict(ExecutionFlow.class, + filter); + } + + public ExecutionContext findExecutionContext(String moduleName, + String moduleVersion) { + String filter = "(&(Bundle-SymbolicName=" + moduleName + + ")(Bundle-Version=" + moduleVersion + "))"; + return bundlesManager.getSingleServiceStrict(ExecutionContext.class, + filter); + } + + public ExecutionFlowDescriptorConverter findExecutionFlowDescriptorConverter( + String moduleName, String moduleVersion) { + String filter = "(&(Bundle-SymbolicName=" + moduleName + + ")(Bundle-Version=" + moduleVersion + "))"; + return bundlesManager.getSingleService( + ExecutionFlowDescriptorConverter.class, filter); + } + + public void setBundlesManager(BundlesManager bundlesManager) { + this.bundlesManager = bundlesManager; + } + + public void afterPropertiesSet() throws Exception { + executionContexts = bundlesManager.newTracker(ExecutionContext.class); + } + + public void destroy() throws Exception { + if (executionContexts != null) + executionContexts.close(); + } + + /** + * Builds a minimal realized flow, based on the provided information + * (typically from the command line). + * + * @param module + * a bundle id, or a pattern contained in a bundle symbolic name + * @param module + * the execution flow name + * @return a minimal realized flow, to be used in an execution + */ + public RealizedFlow findRealizedFlow(String module, String executionName) { + // First check whether we have a bundleId + Long bundleId = null; + try { + bundleId = Long.parseLong(module); + } catch (NumberFormatException e) { + // silent + } + + // Look for bundle names containing pattern + OsgiBundle bundle = null; + if (bundleId != null) { + bundle = bundlesManager.getBundle(bundleId); + } else { + bundle = bundlesManager.findFromPattern(module); + } + + if (bundle != null) { + RealizedFlow launch = new RealizedFlow(); + launch.setModuleName(bundle.getName()); + launch.setModuleVersion(bundle.getVersion()); + ExecutionFlowDescriptor descriptor = new ExecutionFlowDescriptor(); + descriptor.setName(executionName); + launch.setFlowDescriptor(descriptor); + return launch; + } else { + log + .warn("Could not find any execution module matching these requirements."); + return null; + } + } + + public void updateAndExecute(RealizedFlow realizedFlow) { + OsgiBundle osgiBundle = new OsgiBundle(realizedFlow); + bundlesManager.upgradeSynchronous(osgiBundle); + execute(realizedFlow); + } + + public void execute(RealizedFlow realizedFlow) { + if (log.isTraceEnabled()) + log.trace("Executing " + realizedFlow); + + String moduleName = realizedFlow.getModuleName(); + String moduleVersion = realizedFlow.getModuleVersion(); + + ExecutionContext executionContext = findExecutionContext(moduleName, + moduleVersion); + + // Check whether a descriptor converter is published by this module + ExecutionFlowDescriptorConverter descriptorConverter = findExecutionFlowDescriptorConverter( + moduleName, moduleVersion); + + final Map variablesToAdd; + if (descriptorConverter != null) + variablesToAdd = descriptorConverter.convertValues(realizedFlow + .getFlowDescriptor()); + else + variablesToAdd = defaultDescriptorConverter + .convertValues(realizedFlow.getFlowDescriptor()); + + executionContext.addVariables(variablesToAdd); + + ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion, + realizedFlow.getFlowDescriptor().getName()); + + // + // Actually runs the flow, IN THIS THREAD + // + flow.run(); + // + // + // + } + +} diff --git a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiModulesManager.java b/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiModulesManager.java deleted file mode 100644 index 41ee388eb..000000000 --- a/runtime/org.argeo.slc.support.equinox/src/main/java/org/argeo/slc/osgi/OsgiModulesManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.slc.osgi; - -import java.util.List; - -import org.argeo.slc.core.execution.DefaultModulesManager; -import org.argeo.slc.execution.ExecutionModule; - -public class OsgiModulesManager extends DefaultModulesManager { - - - @Override - protected ExecutionModule getExecutionModule(String moduleName, - String version) { - // TODO Auto-generated method stub - return super.getExecutionModule(moduleName, version); - } - - @Override - public List listExecutionModules() { - // TODO Auto-generated method stub - return super.listExecutionModules(); - } - -} diff --git a/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/manager.xml b/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/manager.xml index dcf58c1ac..89bf607c5 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/manager.xml +++ b/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/manager.xml @@ -7,7 +7,10 @@ http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> - + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/osgi.xml b/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/osgi.xml index b3e667aab..7a76831c4 100644 --- a/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/osgi.xml +++ b/runtime/org.argeo.slc.support.equinox/src/main/resources/META-INF/spring/osgi.xml @@ -8,7 +8,7 @@ - + diff --git a/runtime/org.argeo.slc.support.equinox/src/main/resources/org/argeo/slc/osgi/execution/spring.xml b/runtime/org.argeo.slc.support.equinox/src/main/resources/org/argeo/slc/osgi/execution/spring.xml new file mode 100644 index 000000000..c59477e62 --- /dev/null +++ b/runtime/org.argeo.slc.support.equinox/src/main/resources/org/argeo/slc/osgi/execution/spring.xml @@ -0,0 +1,20 @@ + + + + + + + + + org.argeo.slc.execution.ExecutionFlow + + + + + \ No newline at end of file diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultModulesManager.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java similarity index 57% rename from runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultModulesManager.java rename to runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java index b843c4ff0..2db1eb31a 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultModulesManager.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractExecutionModulesManager.java @@ -3,58 +3,33 @@ package org.argeo.slc.core.execution; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.slc.SlcException; +import org.argeo.slc.execution.ExecutionFlow; import org.argeo.slc.execution.ExecutionFlowDescriptor; -import org.argeo.slc.execution.ExecutionModule; import org.argeo.slc.execution.ExecutionModuleDescriptor; import org.argeo.slc.execution.ExecutionModulesManager; +import org.argeo.slc.execution.ExecutionSpec; +import org.argeo.slc.execution.ExecutionSpecAttribute; import org.argeo.slc.process.RealizedFlow; import org.argeo.slc.process.SlcExecution; import org.argeo.slc.process.SlcExecutionNotifier; import org.argeo.slc.process.SlcExecutionStep; +import org.springframework.aop.scope.ScopedObject; +import org.springframework.util.Assert; -public class DefaultModulesManager implements ExecutionModulesManager { +public abstract class AbstractExecutionModulesManager implements + ExecutionModulesManager { private final static Log log = LogFactory - .getLog(DefaultModulesManager.class); + .getLog(AbstractExecutionModulesManager.class); - private List executionModules = new ArrayList(); private List slcExecutionNotifiers = new ArrayList(); private ThreadGroup processesThreadGroup = new ThreadGroup("Processes"); - protected ExecutionModule getExecutionModule(String moduleName, - String version) { - for (ExecutionModule moduleT : executionModules) { - if (moduleT.getName().equals(moduleName)) { - if (moduleT.getVersion().equals(version)) { - return moduleT; - } - } - } - return null; - } - - public ExecutionModuleDescriptor getExecutionModuleDescriptor( - String moduleName, String version) { - ExecutionModule module = getExecutionModule(moduleName, version); - - if (module == null) - throw new SlcException("Module " + moduleName + " (" + version - + ") not found"); - - return module.getDescriptor(); - } - - public List listExecutionModules() { - return executionModules; - } - - public void setExecutionModules(List executionModules) { - this.executionModules = executionModules; - } - public void process(SlcExecution slcExecution) { new ProcessThread(processesThreadGroup, slcExecution).start(); } @@ -83,6 +58,72 @@ public class DefaultModulesManager implements ExecutionModulesManager { this.slcExecutionNotifiers = slcExecutionNotifiers; } + protected static ExecutionModuleDescriptor createDescriptor( + String moduleName, String moduleVersion, + Map executionFlows) { + // TODO: put this in a separate configurable object + ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); + md.setName(moduleName); + md.setVersion(moduleVersion); + + for (String name : executionFlows.keySet()) { + ExecutionFlow executionFlow = executionFlows.get(name); + + Assert.notNull(executionFlow.getName()); + Assert.state(name.equals(executionFlow.getName())); + + ExecutionSpec executionSpec = executionFlow.getExecutionSpec(); + Assert.notNull(executionSpec); + Assert.notNull(executionSpec.getName()); + + Map values = new TreeMap(); + for (String key : executionSpec.getAttributes().keySet()) { + ExecutionSpecAttribute attribute = executionSpec + .getAttributes().get(key); + + if (executionFlow.isSetAsParameter(key)) { + Object value = executionFlow.getParameter(key); + if (attribute instanceof PrimitiveSpecAttribute) { + PrimitiveValue primitiveValue = new PrimitiveValue(); + primitiveValue + .setType(((PrimitiveSpecAttribute) attribute) + .getType()); + primitiveValue.setValue(value); + values.put(key, primitiveValue); + } else if (attribute instanceof RefSpecAttribute) { + RefValue refValue = new RefValue(); + if (value instanceof ScopedObject) { + refValue.setLabel("RUNTIME " + + value.getClass().getName()); + } else { + refValue.setLabel("STATIC " + + value.getClass().getName()); + } + values.put(key, refValue); + } else { + throw new SlcException("Unkown spec attribute type " + + attribute.getClass()); + } + } + + } + + ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, + values, executionSpec); + if (executionFlow.getPath() != null) + efd.setPath(executionFlow.getPath()); + + // Add execution spec if necessary + if (!md.getExecutionSpecs().contains(executionSpec)) + md.getExecutionSpecs().add(executionSpec); + + // Add execution flow + md.getExecutionFlows().add(efd); + } + + return md; + } + /** Thread of the SLC Process, starting the sub executions. */ private class ProcessThread extends Thread { private final SlcExecution slcProcess; @@ -116,17 +157,8 @@ public class DefaultModulesManager implements ExecutionModulesManager { while (flowsToProcess.size() > 0) { RealizedFlow flow = flowsToProcess.remove(0); - ExecutionModule module = getExecutionModule(flow - .getModuleName(), flow.getModuleVersion()); - if (module != null) { - ExecutionThread thread = new ExecutionThread(this, flow - .getFlowDescriptor(), module); - thread.start(); - } else { - throw new SlcException("ExecutionModule " - + flow.getModuleName() + ", version " - + flow.getModuleVersion() + " not found."); - } + ExecutionThread thread = new ExecutionThread(this, flow); + thread.start(); synchronized (this) { try { @@ -157,31 +189,31 @@ public class DefaultModulesManager implements ExecutionModulesManager { /** Thread of a single execution */ private class ExecutionThread extends Thread { - private final ExecutionFlowDescriptor executionFlowDescriptor; - private final ExecutionModule executionModule; + private final RealizedFlow realizedFlow; private final ProcessThread processThread; public ExecutionThread(ProcessThread processThread, - ExecutionFlowDescriptor executionFlowDescriptor, - ExecutionModule executionModule) { + RealizedFlow realizedFlow) { super(processThread.getProcessThreadGroup(), "Flow " - + executionFlowDescriptor.getName()); - this.executionFlowDescriptor = executionFlowDescriptor; - this.executionModule = executionModule; + + realizedFlow.getFlowDescriptor().getName()); + this.realizedFlow = realizedFlow; this.processThread = processThread; } public void run() { + ExecutionFlowDescriptor executionFlowDescriptor = realizedFlow + .getFlowDescriptor(); + String flowName = executionFlowDescriptor.getName(); + dispatchAddStep(processThread.getSlcProcess(), new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START, - "Flow " + executionFlowDescriptor.getName())); + "Flow " + flowName)); try { - executionModule.execute(executionFlowDescriptor); + execute(realizedFlow); } catch (Exception e) { // TODO: re-throw exception ? - String msg = "Execution of flow " - + executionFlowDescriptor.getName() + " failed."; + String msg = "Execution of flow " + flowName + " failed."; log.error(msg, e); dispatchAddStep(processThread.getSlcProcess(), new SlcExecutionStep(msg + " " + e.getMessage())); @@ -189,8 +221,9 @@ public class DefaultModulesManager implements ExecutionModulesManager { processThread.flowCompleted(); dispatchAddStep(processThread.getSlcProcess(), new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END, - "Flow " + executionFlowDescriptor.getName())); + "Flow " + flowName)); } } } + } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java index 1bbf16821..bca30d0ed 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/AbstractSpringExecutionModule.java @@ -19,25 +19,22 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.Assert; -public abstract class AbstractSpringExecutionModule implements ExecutionModule, - ApplicationContextAware { +@Deprecated +public abstract class AbstractSpringExecutionModule implements ExecutionModule + { +/* + protected ApplicationContext applicationContext; - private ApplicationContext applicationContext; + protected ExecutionContext executionContext; - private ExecutionContext executionContext; - - private ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter(); + protected ExecutionFlowDescriptorConverter descriptorConverter = new DefaultDescriptorConverter(); public ExecutionModuleDescriptor getDescriptor() { ExecutionModuleDescriptor md = new ExecutionModuleDescriptor(); md.setName(getName()); md.setVersion(getVersion()); - GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor( - applicationContext); - Map executionFlows = accessor - .getBeansOfType(ExecutionFlow.class); - + Map executionFlows = listFlows(); for (String name : executionFlows.keySet()) { ExecutionFlow executionFlow = executionFlows.get(name); @@ -103,6 +100,14 @@ public abstract class AbstractSpringExecutionModule implements ExecutionModule, return md; } + protected Map listFlows() { + GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor( + applicationContext); + Map executionFlows = accessor + .getBeansOfType(ExecutionFlow.class); + return executionFlows; + } + public void execute(ExecutionFlowDescriptor executionFlowDescriptor) { if (descriptorConverter != null) executionContext.addVariables(descriptorConverter @@ -124,6 +129,6 @@ public abstract class AbstractSpringExecutionModule implements ExecutionModule, public void setDescriptorConverter( ExecutionFlowDescriptorConverter descriptorConverter) { this.descriptorConverter = descriptorConverter; - } + }*/ } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlow.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlow.java index d5c1b19da..497e6520e 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlow.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlow.java @@ -136,15 +136,7 @@ public class DefaultExecutionFlow implements ExecutionFlow, InitializingBean, if (parameters.containsKey(parameterName)) { Object paramValue = parameters.get(parameterName); - if (specAttr instanceof ResourceSpecAttribute) { - // deal with resources - Resource resource = resourceLoader.getResource(paramValue - .toString()); - return ((ResourceSpecAttribute) specAttr) - .convertResource(resource); - } else { - return paramValue; - } + return paramValue; } else { if (specAttr.getValue() != null) { return specAttr.getValue(); diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionScope.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionScope.java index 7deb9f578..a24046a99 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionScope.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ExecutionScope.java @@ -30,11 +30,13 @@ public class ExecutionScope implements Scope { // Check whether we are in an execution // FIXME: do it more properly (not static) // see https://www.argeo.org/bugzilla/show_bug.cgi?id=82 - if (!ExecutionAspect.inModuleExecution.get()) + if (!ExecutionAspect.inModuleExecution.get()) { log - .error("An execution context is being instatiated outside an execution." - + " Please check that your references to execution contexts." + .error("An execution context is being instantiated outside a module execution." + + " Please check your references to execution contexts." + " This may lead to unexpected behaviour and will be rejected in the future."); + //Thread.dumpStack(); + } // store the ExecutionContext in the ThreadLocal executionContext.set((ExecutionContext) obj); @@ -44,7 +46,7 @@ public class ExecutionScope implements Scope { + executionContext.get().getUuid() + " instantiated. (beanName=" + executionContextBeanName.get() + ")"); -// Thread.dumpStack(); + // Thread.dumpStack(); } return obj; } else { diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java deleted file mode 100644 index 8eecc0b47..000000000 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/core/execution/ResourceSpecAttribute.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.argeo.slc.core.execution; - -import java.io.IOException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.slc.SlcException; -import org.springframework.core.io.Resource; - -/** @deprecated */ -public class ResourceSpecAttribute extends AbstractSpecAttribute { - public final static String TYPE_PATH = "path"; - public final static String TYPE_URL = "url"; - public final static String TYPE_STREAM = "stream"; - - private Resource resource; - private String type = TYPE_PATH; - - private final static Log log = LogFactory - .getLog(ResourceSpecAttribute.class); - - public ResourceSpecAttribute() { - log - .warn(getClass() - + " is deprecated and will soon be removed. Please use slcDefault.executionResources instead."); - } - - public Object getValue() { - return convertResource(resource); - } - - public void setResource(Resource resource) { - this.resource = resource; - } - - public Object convertResource(Resource resource) { - try { - if (TYPE_PATH.equals(type)) - return resource.getFile().getCanonicalPath(); - else if (TYPE_URL.equals(type)) - return resource.getURL().toString(); - else if (TYPE_STREAM.equals(type)) - return resource.getInputStream(); - else - throw new SlcException("Unkown type " + type); - } catch (IOException e) { - throw new SlcException("Cannot convert resource " + resource, e); - } - } - - public void setType(String type) { - this.type = type; - } - - public String getType() { - return type; - } - -} diff --git a/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/DefaultModulesManagerTest.java b/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/DefaultModulesManagerTest.java index 5582566e3..c9465f342 100644 --- a/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/DefaultModulesManagerTest.java +++ b/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/DefaultModulesManagerTest.java @@ -17,8 +17,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import junit.framework.TestCase; -public class DefaultModulesManagerTest extends AbstractSpringTestCase { - +public class DefaultModulesManagerTest {//extends AbstractSpringTestCase { +/* public void testSimpleExecution() throws Exception { //do nothing @@ -68,5 +68,5 @@ public class DefaultModulesManagerTest extends AbstractSpringTestCase { applicationContext.start(); return applicationContext; } - + */ } diff --git a/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/ResourceTest.java b/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/ResourceTest.java deleted file mode 100644 index df0824662..000000000 --- a/runtime/org.argeo.slc.support.simple/src/test/java/org/argeo/slc/core/execution/ResourceTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.argeo.slc.core.execution; - - -public class ResourceTest extends AbstractExecutionFlowTestCase { - //private final static Log log = LogFactory.getLog(ResourceTest.class); - - private final String defFile = "resourceTest.xml"; - - public void testResourceSimple() throws Exception { - configureAndExecuteSlcFlow(defFile, "resourceSimple"); - } - - public void testResourceOverridden() throws Exception { - configureAndExecuteSlcFlow(defFile, "resourceOverridden"); - } - -} diff --git a/runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/resourceTest.xml b/runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/resourceTest.xml deleted file mode 100644 index 970a2ed16..000000000 --- a/runtime/org.argeo.slc.support.simple/src/test/resources/org/argeo/slc/core/execution/resourceTest.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/manager.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/manager.xml index da2842aef..7e35ff63a 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/manager.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/manager.xml @@ -4,8 +4,11 @@ xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - - + + + + + \ No newline at end of file diff --git a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml index 0460d7e07..0e92b5c03 100644 --- a/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml +++ b/server/org.argeo.slc.siteserver/bundles/org.argeo.slc.agent/META-INF/spring/osgi.xml @@ -18,10 +18,6 @@ - - - diff --git a/server/org.argeo.slc.siteserver/pom.xml b/server/org.argeo.slc.siteserver/pom.xml index f008417d9..3053f1dea 100644 --- a/server/org.argeo.slc.siteserver/pom.xml +++ b/server/org.argeo.slc.siteserver/pom.xml @@ -15,11 +15,11 @@ bundles - + test + \ No newline at end of file -- 2.39.2