1 package org
.argeo
.slc
.osgi
;
3 import java
.util
.ArrayList
;
4 import java
.util
.HashMap
;
8 import org
.apache
.commons
.logging
.Log
;
9 import org
.apache
.commons
.logging
.LogFactory
;
10 import org
.argeo
.slc
.SlcException
;
11 import org
.argeo
.slc
.core
.execution
.AbstractExecutionModulesManager
;
12 import org
.argeo
.slc
.core
.execution
.DefaultExecutionFlowDescriptorConverter
;
13 import org
.argeo
.slc
.deploy
.ModuleDescriptor
;
14 import org
.argeo
.slc
.execution
.ExecutionContext
;
15 import org
.argeo
.slc
.execution
.ExecutionFlow
;
16 import org
.argeo
.slc
.execution
.ExecutionFlowDescriptor
;
17 import org
.argeo
.slc
.execution
.ExecutionFlowDescriptorConverter
;
18 import org
.argeo
.slc
.execution
.ExecutionModuleDescriptor
;
19 import org
.argeo
.slc
.process
.RealizedFlow
;
20 import org
.osgi
.framework
.Bundle
;
21 import org
.osgi
.framework
.Constants
;
22 import org
.osgi
.framework
.InvalidSyntaxException
;
23 import org
.osgi
.framework
.ServiceReference
;
24 import org
.osgi
.util
.tracker
.ServiceTracker
;
25 import org
.springframework
.beans
.factory
.DisposableBean
;
26 import org
.springframework
.beans
.factory
.InitializingBean
;
28 public class OsgiExecutionModulesManager
extends
29 AbstractExecutionModulesManager
implements InitializingBean
,
31 private final static Log log
= LogFactory
32 .getLog(OsgiExecutionModulesManager
.class);
34 private BundlesManager bundlesManager
;
35 private ServiceTracker executionContexts
;
36 private ExecutionFlowDescriptorConverter defaultDescriptorConverter
= new DefaultExecutionFlowDescriptorConverter();
38 public ExecutionModuleDescriptor
getExecutionModuleDescriptor(
39 String moduleName
, String version
) {
40 ExecutionModuleDescriptor md
= new ExecutionModuleDescriptor();
41 md
.setName(moduleName
);
42 md
.setVersion(version
);
43 setMetadataFromBundle(md
, null);
44 getExecutionFlowDescriptorConverter(moduleName
, version
)
45 .addFlowsToDescriptor(md
, listFlows(moduleName
, version
));
49 public List
<ExecutionModuleDescriptor
> listExecutionModules() {
50 List
<ExecutionModuleDescriptor
> descriptors
= new ArrayList
<ExecutionModuleDescriptor
>();
52 ServiceReference
[] srs
= executionContexts
.getServiceReferences();
53 for (ServiceReference sr
: srs
) {
54 ExecutionModuleDescriptor md
= new ExecutionModuleDescriptor();
55 setMetadataFromBundle(md
, sr
.getBundle());
61 protected Map
<String
, ExecutionFlow
> listFlows(String moduleName
,
62 String moduleVersion
) {
63 // TODO: use service trackers?
64 // String filter = OsgiFilterUtils.unifyFilter(ExecutionFlow.class,
67 String filter
= "(Bundle-SymbolicName=" + moduleName
+ ")";
68 ServiceReference
[] sfs
;
70 sfs
= bundlesManager
.getBundleContext().getServiceReferences(
71 ExecutionFlow
.class.getName(), filter
);
72 } catch (InvalidSyntaxException e
) {
73 throw new SlcException(
74 "Cannot retrieve service reference for flow " + filter
, e
);
77 Map
<String
, ExecutionFlow
> flows
= new HashMap
<String
, ExecutionFlow
>();
78 for (ServiceReference sf
: sfs
) {
79 ExecutionFlow flow
= (ExecutionFlow
) bundlesManager
80 .getBundleContext().getService(sf
);
81 flows
.put(flow
.getName(), flow
);
86 public ExecutionFlow
findExecutionFlow(String moduleName
,
87 String moduleVersion
, String flowName
) {
88 String filter
= "(&(Bundle-SymbolicName=" + moduleName
89 + ")(org.springframework.osgi.bean.name=" + flowName
+ "))";
90 return bundlesManager
.getSingleServiceStrict(ExecutionFlow
.class,
94 public ExecutionContext
findExecutionContext(String moduleName
,
95 String moduleVersion
) {
96 String filter
= "(&(Bundle-SymbolicName=" + moduleName
97 + ")(Bundle-Version=" + moduleVersion
+ "))";
98 return bundlesManager
.getSingleServiceStrict(ExecutionContext
.class,
102 public ExecutionFlowDescriptorConverter
findExecutionFlowDescriptorConverter(
103 String moduleName
, String moduleVersion
) {
104 String filter
= "(&(Bundle-SymbolicName=" + moduleName
105 + ")(Bundle-Version=" + moduleVersion
+ "))";
106 return bundlesManager
.getSingleService(
107 ExecutionFlowDescriptorConverter
.class, filter
);
110 public void setBundlesManager(BundlesManager bundlesManager
) {
111 this.bundlesManager
= bundlesManager
;
114 public void afterPropertiesSet() throws Exception
{
115 executionContexts
= bundlesManager
.newTracker(ExecutionContext
.class);
118 public void destroy() throws Exception
{
119 if (executionContexts
!= null)
120 executionContexts
.close();
124 * Builds a minimal realized flow, based on the provided information
125 * (typically from the command line).
128 * a bundle id, or a pattern contained in a bundle symbolic name
130 * the execution flow name
131 * @return a minimal realized flow, to be used in an execution
133 public RealizedFlow
findRealizedFlow(String module
, String executionName
) {
134 // First check whether we have a bundleId
135 Long bundleId
= null;
137 bundleId
= Long
.parseLong(module
);
138 } catch (NumberFormatException e
) {
142 // Look for bundle names containing pattern
143 OsgiBundle bundle
= null;
144 if (bundleId
!= null) {
145 bundle
= bundlesManager
.getBundle(bundleId
);
147 bundle
= bundlesManager
.findFromPattern(module
);
150 if (bundle
!= null) {
151 RealizedFlow launch
= new RealizedFlow();
152 launch
.setModuleName(bundle
.getName());
153 launch
.setModuleVersion(bundle
.getVersion());
154 ExecutionFlowDescriptor descriptor
= new ExecutionFlowDescriptor();
155 descriptor
.setName(executionName
);
156 launch
.setFlowDescriptor(descriptor
);
160 .warn("Could not find any execution module matching these requirements.");
165 public void updateAndExecute(RealizedFlow realizedFlow
) {
166 OsgiBundle osgiBundle
= new OsgiBundle(realizedFlow
);
167 bundlesManager
.upgradeSynchronous(osgiBundle
);
168 execute(realizedFlow
);
171 protected ExecutionFlowDescriptorConverter
getExecutionFlowDescriptorConverter(
172 String moduleName
, String moduleVersion
) {
173 // Check whether a descriptor converter is published by this module
174 ExecutionFlowDescriptorConverter descriptorConverter
= findExecutionFlowDescriptorConverter(
175 moduleName
, moduleVersion
);
176 if (descriptorConverter
== null)
177 return defaultDescriptorConverter
;
179 return descriptorConverter
;
182 public void execute(RealizedFlow realizedFlow
) {
183 if (log
.isTraceEnabled())
184 log
.trace("Executing " + realizedFlow
);
186 String moduleName
= realizedFlow
.getModuleName();
187 String moduleVersion
= realizedFlow
.getModuleVersion();
189 Map
<?
extends String
, ?
extends Object
> variablesToAdd
= getExecutionFlowDescriptorConverter(
190 moduleName
, moduleVersion
).convertValues(
191 realizedFlow
.getFlowDescriptor());
192 ExecutionContext executionContext
= findExecutionContext(moduleName
,
194 for (String key
: variablesToAdd
.keySet())
195 executionContext
.setVariable(key
, variablesToAdd
.get(key
));
197 ExecutionFlow flow
= findExecutionFlow(moduleName
, moduleVersion
,
198 realizedFlow
.getFlowDescriptor().getName());
201 // Actually runs the flow, IN THIS THREAD
209 public ModuleDescriptor
getModuleDescriptor(String moduleName
,
211 return getExecutionModuleDescriptor(moduleName
, version
);
214 public List
<ModuleDescriptor
> listModules() {
215 Bundle
[] bundles
= bundlesManager
.getBundleContext().getBundles();
216 List
<ModuleDescriptor
> lst
= new ArrayList
<ModuleDescriptor
>();
217 for (Bundle bundle
: bundles
) {
218 ModuleDescriptor moduleDescriptor
= new ModuleDescriptor();
219 setMetadataFromBundle(moduleDescriptor
, bundle
);
220 lst
.add(moduleDescriptor
);
225 protected void setMetadataFromBundle(ModuleDescriptor md
, Bundle bundle
) {
228 if (md
.getName() == null || md
.getVersion() == null)
229 throw new SlcException("Name and version not available.");
231 Bundle
[] bundles
= bundlesManager
.getBundleContext().getBundles();
232 for (Bundle b
: bundles
) {
233 if (b
.getSymbolicName().equals(md
.getName())
234 && md
.getVersion().equals(
235 getHeaderSafe(b
, Constants
.BUNDLE_VERSION
))) {
244 throw new SlcException("Cannot find bundle.");
246 md
.setName(bdl
.getSymbolicName());
247 md
.setVersion(getHeaderSafe(bdl
, Constants
.BUNDLE_VERSION
));
248 md
.setLabel(getHeaderSafe(bdl
, Constants
.BUNDLE_NAME
));
249 md
.setDescription(getHeaderSafe(bdl
, Constants
.BUNDLE_DESCRIPTION
));
252 private String
getHeaderSafe(Bundle bundle
, Object key
) {
253 Object obj
= bundle
.getHeaders().get(key
);
257 return obj
.toString();