<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
<bundle id="basic" symbolic-name="org.argeo.slc.demo.basic"
action="start" />
+ <bundle id="minimal" symbolic-name="org.argeo.slc.demo.minimal"
+ action="start" />
</beans:beans>
\ No newline at end of file
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
\r
- <bean id="executionModule" class="org.argeo.slc.osgi.OsgiExecutionModule">\r
- <property name="executionContext">\r
- <ref bean="executionContext" />\r
- </property>\r
- </bean>\r
-\r
<bean id="main" parent="slcTemplate.simpleFlow">\r
<constructor-arg>\r
<bean parent="slcTemplate.simpleSpec">\r
http://www.springframework.org/schema/beans \r
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
\r
- <service interface="org.argeo.slc.execution.ExecutionModule"\r
- ref="executionModule" />\r
+ <beans:import resource="classpath:org/argeo/slc/osgi/execution/spring.xml" />\r
\r
<reference id="attachmentUploader" interface="org.argeo.slc.core.attachment.AttachmentUploader" />\r
\r
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<String> getBundlesToStart() {
bundlesToStart.add("org.argeo.slc.demo.basic");
return bundlesToStart;
}
-*/
+
}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+# Set root logger level to DEBUG and its only appender to A1.\r
+log4j.rootLogger=WARN, console\r
+\r
+## Levels\r
+# Slc\r
+log4j.logger.org.argeo.slc=DEBUG\r
+log4j.logger.org.springframework=WARN\r
+\r
+## Appenders\r
+# A1 is set to be a ConsoleAppender.\r
+log4j.appender.console=org.apache.log4j.ConsoleAppender\r
+\r
+# A1 uses PatternLayout.\r
+log4j.appender.console.layout=org.apache.log4j.PatternLayout\r
+log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c %n\r
+\r
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);*/
}
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<ExecutionModule> listExecutionModules();
+ /**
+ * @return a list of minimal execution module descriptors (only the module
+ * meta data, not the flows)
+ */
+ public List<ExecutionModuleDescriptor> 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);
}
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
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;
}
public List<ExecutionModuleDescriptor> listExecutionModuleDescriptors() {
- List<ExecutionModule> modules = getModulesManager()
- .listExecutionModules();
-
- List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
- 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() {
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;
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
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);
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);
}
}
- public void setExecutionLauncher(OsgiExecutionLauncher launcher) {
- this.executionLauncher = launcher;
+ public void setModulesManager(OsgiExecutionModulesManager osgiModulesManager) {
+ this.modulesManager = osgiModulesManager;
}
public void afterPropertiesSet() throws Exception {
}
}
-
- // public void setBundleContext(BundleContext bundleContext) {
- // this.bundleContext = bundleContext;
- // }
-
- // public void setBundlesManager(BundlesManager bundlesManager) {
- // this.bundlesManager = bundlesManager;
- // }
-
}
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);
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;
}
/** 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;
}
/** 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;
}
/** 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
}
}
- public List<ApplicationContext> listPublishedApplicationContexts(
- String filter) {
- try {
- List<ApplicationContext> lst = new ArrayList<ApplicationContext>();
- 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())
}
}
+ /** 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> T getSingleService(Class<T> 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> T getSingleServiceStrict(Class<T> 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;
}
this.defaultTimeout = defaultTimeout;
}
+ /** Temporary internal access for {@link OsgiExecutionModulesManager} */
+ BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
}
--- /dev/null
+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<Class> interfaces = new ArrayList<Class>();
+
+ 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<String> beanNames = new HashSet<String>();
+ 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<Class> interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ public void setOsgiServiceFactoryClass(Class osgiServiceFactoryClass) {
+ this.osgiServiceFactoryClass = osgiServiceFactoryClass;
+ }
+
+}
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<ResourceDistribution> {
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() {
}
public DeploymentData getDeploymentData() {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException();
}
public Distribution getDistribution() {
}
public TargetData getTargetData() {
- // TODO Auto-generated method stub
- return null;
+ throw new UnsupportedOperationException();
}
public String getName() {
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;
+ }
+
}
+++ /dev/null
-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;
- }
-
- }
-}
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: <service interface=\"org.argeo.slc.execution.ExecutionModule\" ref=\"executionModule\" />");
+ log
+ .error("by: <beans:import resource=\"classpath:org/argeo/slc/osgi/execution/spring.xml\" /> ");
+ 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<String, ExecutionFlow> 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<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+ * 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]); }
+ */
}
--- /dev/null
+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<ExecutionModuleDescriptor> listExecutionModules() {
+ List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
+
+ 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<String, ExecutionFlow> 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<String, ExecutionFlow> flows = new HashMap<String, ExecutionFlow>();
+ 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<? extends String, ? extends Object> 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();
+ //
+ //
+ //
+ }
+
+}
+++ /dev/null
-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<ExecutionModule> listExecutionModules() {
- // TODO Auto-generated method stub
- return super.listExecutionModules();
- }
-
-}
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd\r
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
\r
- <bean id="executionLauncher" class="org.argeo.slc.osgi.OsgiExecutionLauncher"\r
- p:bundlesManager-ref="bundlesManager" />\r
<bean id="bundlesManager" class="org.argeo.slc.osgi.BundlesManager" />\r
+\r
+ <bean id="modulesManager" class="org.argeo.slc.osgi.OsgiExecutionModulesManager">\r
+ <property name="bundlesManager" ref="bundlesManager" />\r
+ </bean>\r
+\r
</beans>
\ No newline at end of file
\r
<service interface="org.eclipse.osgi.framework.console.CommandProvider">\r
<beans:bean class="org.argeo.slc.equinox.ExecutionCommandProvider">\r
- <beans:property name="executionLauncher" ref="executionLauncher" />\r
+ <beans:property name="modulesManager" ref="modulesManager" />\r
</beans:bean>\r
</service>\r
\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans xmlns:osgi="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
+\r
+ <osgi:service interface="org.argeo.slc.execution.ExecutionContext"\r
+ ref="executionContext" />\r
+\r
+ <bean class="org.argeo.slc.osgi.MultipleServiceExporterPostProcessor">\r
+ <property name="interfaces">\r
+ <list>\r
+ <value>org.argeo.slc.execution.ExecutionFlow\r
+ </value>\r
+ </list>\r
+ </property>\r
+ </bean>\r
+</beans>
\ No newline at end of file
--- /dev/null
+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.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 abstract class AbstractExecutionModulesManager implements
+ ExecutionModulesManager {
+ private final static Log log = LogFactory
+ .getLog(AbstractExecutionModulesManager.class);
+
+ private List<SlcExecutionNotifier> slcExecutionNotifiers = new ArrayList<SlcExecutionNotifier>();
+ private ThreadGroup processesThreadGroup = new ThreadGroup("Processes");
+
+ public void process(SlcExecution slcExecution) {
+ new ProcessThread(processesThreadGroup, slcExecution).start();
+ }
+
+ protected void dispatchUpdateStatus(SlcExecution slcExecution,
+ String oldStatus, String newStatus) {
+ for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
+ .iterator(); it.hasNext();) {
+ it.next().updateStatus(slcExecution, oldStatus, newStatus);
+ }
+ }
+
+ protected synchronized void dispatchAddStep(SlcExecution slcExecution,
+ SlcExecutionStep step) {
+ slcExecution.getSteps().add(step);
+ List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();
+ steps.add(step);
+ for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
+ .iterator(); it.hasNext();) {
+ it.next().addSteps(slcExecution, steps);
+ }
+ }
+
+ public void setSlcExecutionNotifiers(
+ List<SlcExecutionNotifier> slcExecutionNotifiers) {
+ this.slcExecutionNotifiers = slcExecutionNotifiers;
+ }
+
+ protected static ExecutionModuleDescriptor createDescriptor(
+ String moduleName, String moduleVersion,
+ Map<String, ExecutionFlow> 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<String, Object> values = new TreeMap<String, Object>();
+ 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;
+ private final ThreadGroup processThreadGroup;
+ private final List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
+
+ public ProcessThread(ThreadGroup processesThreadGroup,
+ SlcExecution slcExecution) {
+ super(processesThreadGroup, "SLC Process #"
+ + slcExecution.getUuid());
+ this.slcProcess = slcExecution;
+ processThreadGroup = new ThreadGroup("SLC Process #"
+ + slcExecution.getUuid() + " thread group");
+ }
+
+ public void run() {
+ log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n");
+
+ // FIXME: hack to let the SlcExecution be registered on server
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e1) {
+ // silent
+ }
+
+ slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
+ dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
+ SlcExecution.STATUS_RUNNING);
+
+ flowsToProcess.addAll(slcProcess.getRealizedFlows());
+
+ while (flowsToProcess.size() > 0) {
+ RealizedFlow flow = flowsToProcess.remove(0);
+ ExecutionThread thread = new ExecutionThread(this, flow);
+ thread.start();
+
+ synchronized (this) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // silent
+ }
+ }
+ }
+
+ slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
+ dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
+ SlcExecution.STATUS_FINISHED);
+ }
+
+ public synchronized void flowCompleted() {
+ notifyAll();
+ }
+
+ public SlcExecution getSlcProcess() {
+ return slcProcess;
+ }
+
+ public ThreadGroup getProcessThreadGroup() {
+ return processThreadGroup;
+ }
+ }
+
+ /** Thread of a single execution */
+ private class ExecutionThread extends Thread {
+ private final RealizedFlow realizedFlow;
+ private final ProcessThread processThread;
+
+ public ExecutionThread(ProcessThread processThread,
+ RealizedFlow realizedFlow) {
+ super(processThread.getProcessThreadGroup(), "Flow "
+ + 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 " + flowName));
+
+ try {
+ execute(realizedFlow);
+ } catch (Exception e) {
+ // TODO: re-throw exception ?
+ String msg = "Execution of flow " + flowName + " failed.";
+ log.error(msg, e);
+ dispatchAddStep(processThread.getSlcProcess(),
+ new SlcExecutionStep(msg + " " + e.getMessage()));
+ } finally {
+ processThread.flowCompleted();
+ dispatchAddStep(processThread.getSlcProcess(),
+ new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END,
+ "Flow " + flowName));
+ }
+ }
+ }
+
+}
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<String, ExecutionFlow> executionFlows = accessor
- .getBeansOfType(ExecutionFlow.class);
-
+ Map<String, ExecutionFlow> executionFlows = listFlows();
for (String name : executionFlows.keySet()) {
ExecutionFlow executionFlow = executionFlows.get(name);
return md;
}
+ protected Map<String, ExecutionFlow> listFlows() {
+ GenericBeanFactoryAccessor accessor = new GenericBeanFactoryAccessor(
+ applicationContext);
+ Map<String, ExecutionFlow> executionFlows = accessor
+ .getBeansOfType(ExecutionFlow.class);
+ return executionFlows;
+ }
+
public void execute(ExecutionFlowDescriptor executionFlowDescriptor) {
if (descriptorConverter != null)
executionContext.addVariables(descriptorConverter
public void setDescriptorConverter(
ExecutionFlowDescriptorConverter descriptorConverter) {
this.descriptorConverter = descriptorConverter;
- }
+ }*/
}
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();
+++ /dev/null
-package org.argeo.slc.core.execution;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-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.execution.ExecutionModuleDescriptor;
-import org.argeo.slc.execution.ExecutionModulesManager;
-import org.argeo.slc.process.RealizedFlow;
-import org.argeo.slc.process.SlcExecution;
-import org.argeo.slc.process.SlcExecutionNotifier;
-import org.argeo.slc.process.SlcExecutionStep;
-
-public class DefaultModulesManager implements ExecutionModulesManager {
- private final static Log log = LogFactory
- .getLog(DefaultModulesManager.class);
-
- private List<ExecutionModule> executionModules = new ArrayList<ExecutionModule>();
- private List<SlcExecutionNotifier> slcExecutionNotifiers = new ArrayList<SlcExecutionNotifier>();
- 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<ExecutionModule> listExecutionModules() {
- return executionModules;
- }
-
- public void setExecutionModules(List<ExecutionModule> executionModules) {
- this.executionModules = executionModules;
- }
-
- public void process(SlcExecution slcExecution) {
- new ProcessThread(processesThreadGroup, slcExecution).start();
- }
-
- protected void dispatchUpdateStatus(SlcExecution slcExecution,
- String oldStatus, String newStatus) {
- for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
- .iterator(); it.hasNext();) {
- it.next().updateStatus(slcExecution, oldStatus, newStatus);
- }
- }
-
- protected synchronized void dispatchAddStep(SlcExecution slcExecution,
- SlcExecutionStep step) {
- slcExecution.getSteps().add(step);
- List<SlcExecutionStep> steps = new ArrayList<SlcExecutionStep>();
- steps.add(step);
- for (Iterator<SlcExecutionNotifier> it = slcExecutionNotifiers
- .iterator(); it.hasNext();) {
- it.next().addSteps(slcExecution, steps);
- }
- }
-
- public void setSlcExecutionNotifiers(
- List<SlcExecutionNotifier> slcExecutionNotifiers) {
- this.slcExecutionNotifiers = slcExecutionNotifiers;
- }
-
- /** Thread of the SLC Process, starting the sub executions. */
- private class ProcessThread extends Thread {
- private final SlcExecution slcProcess;
- private final ThreadGroup processThreadGroup;
- private final List<RealizedFlow> flowsToProcess = new ArrayList<RealizedFlow>();
-
- public ProcessThread(ThreadGroup processesThreadGroup,
- SlcExecution slcExecution) {
- super(processesThreadGroup, "SLC Process #"
- + slcExecution.getUuid());
- this.slcProcess = slcExecution;
- processThreadGroup = new ThreadGroup("SLC Process #"
- + slcExecution.getUuid() + " thread group");
- }
-
- public void run() {
- log.info("\n##\n## Process SLC Execution " + slcProcess + "\n##\n");
-
- // FIXME: hack to let the SlcExecution be registered on server
- try {
- Thread.sleep(500);
- } catch (InterruptedException e1) {
- // silent
- }
-
- slcProcess.setStatus(SlcExecution.STATUS_RUNNING);
- dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_SCHEDULED,
- SlcExecution.STATUS_RUNNING);
-
- flowsToProcess.addAll(slcProcess.getRealizedFlows());
-
- 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.");
- }
-
- synchronized (this) {
- try {
- wait();
- } catch (InterruptedException e) {
- // silent
- }
- }
- }
-
- slcProcess.setStatus(SlcExecution.STATUS_FINISHED);
- dispatchUpdateStatus(slcProcess, SlcExecution.STATUS_RUNNING,
- SlcExecution.STATUS_FINISHED);
- }
-
- public synchronized void flowCompleted() {
- notifyAll();
- }
-
- public SlcExecution getSlcProcess() {
- return slcProcess;
- }
-
- public ThreadGroup getProcessThreadGroup() {
- return processThreadGroup;
- }
- }
-
- /** Thread of a single execution */
- private class ExecutionThread extends Thread {
- private final ExecutionFlowDescriptor executionFlowDescriptor;
- private final ExecutionModule executionModule;
- private final ProcessThread processThread;
-
- public ExecutionThread(ProcessThread processThread,
- ExecutionFlowDescriptor executionFlowDescriptor,
- ExecutionModule executionModule) {
- super(processThread.getProcessThreadGroup(), "Flow "
- + executionFlowDescriptor.getName());
- this.executionFlowDescriptor = executionFlowDescriptor;
- this.executionModule = executionModule;
- this.processThread = processThread;
- }
-
- public void run() {
- dispatchAddStep(processThread.getSlcProcess(),
- new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_START,
- "Flow " + executionFlowDescriptor.getName()));
-
- try {
- executionModule.execute(executionFlowDescriptor);
- } catch (Exception e) {
- // TODO: re-throw exception ?
- String msg = "Execution of flow "
- + executionFlowDescriptor.getName() + " failed.";
- log.error(msg, e);
- dispatchAddStep(processThread.getSlcProcess(),
- new SlcExecutionStep(msg + " " + e.getMessage()));
- } finally {
- processThread.flowCompleted();
- dispatchAddStep(processThread.getSlcProcess(),
- new SlcExecutionStep(SlcExecutionStep.TYPE_PHASE_END,
- "Flow " + executionFlowDescriptor.getName()));
- }
- }
- }
-}
// 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);
+ executionContext.get().getUuid()
+ " instantiated. (beanName="
+ executionContextBeanName.get() + ")");
-// Thread.dumpStack();
+ // Thread.dumpStack();
}
return obj;
} else {
+++ /dev/null
-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;
- }
-
-}
\r
import junit.framework.TestCase;\r
\r
-public class DefaultModulesManagerTest extends AbstractSpringTestCase {\r
-\r
+public class DefaultModulesManagerTest {//extends AbstractSpringTestCase {\r
+/*\r
public void testSimpleExecution() throws Exception {\r
//do nothing\r
\r
applicationContext.start();\r
return applicationContext;\r
} \r
- \r
+ */\r
}\r
+++ /dev/null
-package org.argeo.slc.core.execution;\r
-\r
-\r
-public class ResourceTest extends AbstractExecutionFlowTestCase {\r
- //private final static Log log = LogFactory.getLog(ResourceTest.class);\r
-\r
- private final String defFile = "resourceTest.xml";\r
-\r
- public void testResourceSimple() throws Exception {\r
- configureAndExecuteSlcFlow(defFile, "resourceSimple");\r
- }\r
-\r
- public void testResourceOverridden() throws Exception {\r
- configureAndExecuteSlcFlow(defFile, "resourceOverridden");\r
- }\r
-\r
-}\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<beans xmlns="http://www.springframework.org/schema/beans"\r
- xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
- xmlns:aop="http://www.springframework.org/schema/aop"\r
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">\r
-\r
- <import resource="imports.xml" />\r
-\r
- <bean id="resourceSimple" parent="slcTemplate.simpleFlow">\r
- <constructor-arg>\r
- <bean parent="slcTemplate.simpleSpec">\r
- <property name="attributes">\r
- <map>\r
- <entry key="var">\r
- <bean parent="specAttr.resource"\r
- p:resource="classpath:/org/argeo/slc/core/execution/tasks/core.xml" />\r
- </entry>\r
- </map>\r
- </property>\r
- </bean>\r
- </constructor-arg>\r
- <property name="executables">\r
- <list>\r
- <bean parent="task.echo" scope="execution">\r
- <property name="message" value="echo var=@{var}" />\r
- <aop:scoped-proxy />\r
- </bean>\r
- </list>\r
- </property>\r
- </bean>\r
-\r
- <bean id="resourceOverridden" parent="resourceSimple">\r
- <constructor-arg>\r
- <map>\r
- <entry key="var" value="classpath:/org/argeo/slc/core/execution/specs.xml" />\r
- </map>\r
- </constructor-arg>\r
- </bean>\r
-</beans>
\ No newline at end of file
xsi:schemaLocation="\r
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">\r
\r
- <bean id="modulesManager" class="org.argeo.slc.core.execution.DefaultModulesManager">\r
- <property name="executionModules" ref="executionModules" />\r
+ <bean id="modulesManager" class="org.argeo.slc.osgi.OsgiExecutionModulesManager">\r
<property name="slcExecutionNotifiers" ref="slcExecutionListeners" />\r
+ <property name="bundlesManager" ref="bundlesManager" />\r
</bean>\r
+\r
+ <bean id="bundlesManager" class="org.argeo.slc.osgi.BundlesManager" />\r
+\r
</beans>
\ No newline at end of file
\r
<service ref="slcExecutionListener" interface="org.argeo.slc.process.SlcExecutionNotifier" />\r
\r
- <!-- Manager -->\r
- <list id="executionModules" interface="org.argeo.slc.execution.ExecutionModule"\r
- cardinality="0..N" />\r
-\r
<service ref="modulesManager" interface="org.argeo.slc.execution.ExecutionModulesManager" />\r
\r
<service ref="jmsAgent.attachmentUploader" interface="org.argeo.slc.core.attachment.AttachmentUploader" />\r
<module>bundles</module>
</modules>
<dependencies>
- <!--
<dependency>
<groupId>org.argeo.slc.dep</groupId>
<artifactId>org.argeo.slc.dep.server</artifactId>
<version>${project.version}</version>
- </dependency> -->
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file