]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiExecutionModulesManager.java
Improve log
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.osgi / src / main / java / org / argeo / slc / osgi / OsgiExecutionModulesManager.java
1 package org.argeo.slc.osgi;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
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;
27
28 public class OsgiExecutionModulesManager extends
29 AbstractExecutionModulesManager implements InitializingBean,
30 DisposableBean {
31 private final static Log log = LogFactory
32 .getLog(OsgiExecutionModulesManager.class);
33
34 private BundlesManager bundlesManager;
35 private ServiceTracker executionContexts;
36 private ExecutionFlowDescriptorConverter defaultDescriptorConverter = new DefaultExecutionFlowDescriptorConverter();
37
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));
46 return md;
47 }
48
49 public List<ExecutionModuleDescriptor> listExecutionModules() {
50 List<ExecutionModuleDescriptor> descriptors = new ArrayList<ExecutionModuleDescriptor>();
51
52 ServiceReference[] srs = executionContexts.getServiceReferences();
53 for (ServiceReference sr : srs) {
54 ExecutionModuleDescriptor md = new ExecutionModuleDescriptor();
55 setMetadataFromBundle(md, sr.getBundle());
56 descriptors.add(md);
57 }
58 return descriptors;
59 }
60
61 protected Map<String, ExecutionFlow> listFlows(String moduleName,
62 String moduleVersion) {
63 // TODO: use service trackers?
64 // String filter = OsgiFilterUtils.unifyFilter(ExecutionFlow.class,
65 // null);
66
67 String filter = "(Bundle-SymbolicName=" + moduleName + ")";
68 ServiceReference[] sfs;
69 try {
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);
75 }
76
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);
82 }
83 return flows;
84 }
85
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,
91 filter);
92 }
93
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,
99 filter);
100 }
101
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);
108 }
109
110 public void setBundlesManager(BundlesManager bundlesManager) {
111 this.bundlesManager = bundlesManager;
112 }
113
114 public void afterPropertiesSet() throws Exception {
115 executionContexts = bundlesManager.newTracker(ExecutionContext.class);
116 }
117
118 public void destroy() throws Exception {
119 if (executionContexts != null)
120 executionContexts.close();
121 }
122
123 /**
124 * Builds a minimal realized flow, based on the provided information
125 * (typically from the command line).
126 *
127 * @param module
128 * a bundle id, or a pattern contained in a bundle symbolic name
129 * @param module
130 * the execution flow name
131 * @return a minimal realized flow, to be used in an execution
132 */
133 public RealizedFlow findRealizedFlow(String module, String executionName) {
134 // First check whether we have a bundleId
135 Long bundleId = null;
136 try {
137 bundleId = Long.parseLong(module);
138 } catch (NumberFormatException e) {
139 // silent
140 }
141
142 // Look for bundle names containing pattern
143 OsgiBundle bundle = null;
144 if (bundleId != null) {
145 bundle = bundlesManager.getBundle(bundleId);
146 } else {
147 bundle = bundlesManager.findFromPattern(module);
148 }
149
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);
157 return launch;
158 } else {
159 log
160 .warn("Could not find any execution module matching these requirements.");
161 return null;
162 }
163 }
164
165 public void updateAndExecute(RealizedFlow realizedFlow) {
166 OsgiBundle osgiBundle = new OsgiBundle(realizedFlow);
167 bundlesManager.upgradeSynchronous(osgiBundle);
168 execute(realizedFlow);
169 }
170
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;
178 else
179 return descriptorConverter;
180 }
181
182 public void execute(RealizedFlow realizedFlow) {
183 if (log.isTraceEnabled())
184 log.trace("Executing " + realizedFlow);
185
186 String moduleName = realizedFlow.getModuleName();
187 String moduleVersion = realizedFlow.getModuleVersion();
188
189 Map<? extends String, ? extends Object> variablesToAdd = getExecutionFlowDescriptorConverter(
190 moduleName, moduleVersion).convertValues(
191 realizedFlow.getFlowDescriptor());
192 ExecutionContext executionContext = findExecutionContext(moduleName,
193 moduleVersion);
194 for (String key : variablesToAdd.keySet())
195 executionContext.setVariable(key, variablesToAdd.get(key));
196
197 ExecutionFlow flow = findExecutionFlow(moduleName, moduleVersion,
198 realizedFlow.getFlowDescriptor().getName());
199
200 //
201 // Actually runs the flow, IN THIS THREAD
202 //
203 flow.run();
204 //
205 //
206 //
207 }
208
209 public ModuleDescriptor getModuleDescriptor(String moduleName,
210 String version) {
211 return getExecutionModuleDescriptor(moduleName, version);
212 }
213
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);
221 }
222 return lst;
223 }
224
225 protected void setMetadataFromBundle(ModuleDescriptor md, Bundle bundle) {
226 Bundle bdl = bundle;
227 if (bdl == null) {
228 if (md.getName() == null || md.getVersion() == null)
229 throw new SlcException("Name and version not available.");
230
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))) {
236 bdl = b;
237 break;
238 }
239 }
240
241 }
242
243 if (bdl == null)
244 throw new SlcException("Cannot find bundle.");
245
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));
250 }
251
252 private String getHeaderSafe(Bundle bundle, Object key) {
253 Object obj = bundle.getHeaders().get(key);
254 if (obj == null)
255 return null;
256 else
257 return obj.toString();
258 }
259 }