1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.applications.component;
12
13 import org.astrogrid.applications.contracts.Configuration;
14 import org.astrogrid.applications.manager.AppAuthorityIDResolver;
15 import org.astrogrid.applications.description.ApplicationDescription;
16 import org.astrogrid.applications.description.ApplicationDescriptionLibrary;
17 import org.astrogrid.applications.description.BaseApplicationDescriptionLibrary;
18 import org.astrogrid.applications.description.CompositeApplicationDescriptionLibrary;
19 import org.astrogrid.applications.description.base.ApplicationDescriptionEnvironment;
20 import org.astrogrid.applications.description.registry.RegistryAdminLocator;
21 import org.astrogrid.applications.description.registry.RegistryAdminLocatorImpl;
22 import org.astrogrid.applications.description.registry.RegistryUploader;
23 import org.astrogrid.applications.manager.ApplicationEnvironmentRetriver;
24 import org.astrogrid.applications.manager.BaseConfiguration;
25 import org.astrogrid.applications.manager.CeaThreadPool;
26 import org.astrogrid.applications.manager.ControlService;
27 import org.astrogrid.applications.manager.DefaultAppAuthorityIDResolver;
28 import org.astrogrid.applications.manager.DefaultApplicationEnvironmentRetriever;
29 import org.astrogrid.applications.manager.DefaultMetadataService;
30 import org.astrogrid.applications.manager.DefaultQueryService;
31 import org.astrogrid.applications.manager.ExecutionController;
32 import org.astrogrid.applications.manager.MetadataService;
33 import org.astrogrid.applications.manager.QueryService;
34 import org.astrogrid.applications.manager.ThreadPoolExecutionController;
35 import org.astrogrid.applications.manager.idgen.GloballyUniqueIdGen;
36 import org.astrogrid.applications.manager.idgen.IdGen;
37 import org.astrogrid.applications.manager.persist.ExecutionHistory;
38 import org.astrogrid.applications.manager.persist.FileStoreExecutionHistory;
39 import org.astrogrid.applications.manager.persist.InMemoryExecutionHistory;
40 import org.astrogrid.applications.parameter.protocol.DefaultProtocolLibrary;
41 import org.astrogrid.applications.parameter.protocol.FileProtocol;
42 import org.astrogrid.applications.parameter.protocol.FtpProtocol;
43 import org.astrogrid.applications.parameter.protocol.HttpProtocol;
44 import org.astrogrid.applications.parameter.protocol.IvornProtocol;
45 import org.astrogrid.applications.parameter.protocol.Protocol;
46 import org.astrogrid.applications.parameter.protocol.ProtocolLibrary;
47 import org.astrogrid.component.EmptyComponentManager;
48 import org.astrogrid.config.Config;
49 import org.astrogrid.config.SimpleConfig;
50 import org.astrogrid.registry.client.RegistryDelegateFactory;
51 import org.astrogrid.registry.client.admin.RegistryAdminService;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55 import org.picocontainer.ComponentAdapter;
56 import org.picocontainer.MutablePicoContainer;
57 import org.picocontainer.Startable;
58
59 import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
60
61 import java.io.File;
62 import java.net.MalformedURLException;
63 import java.net.URL;
64 import java.util.Iterator;
65
66 /*** empty implementation of {@link org.astrogrid.applications.component.CEAComponentManager}
67 * provides implementations of the accessor methods, but no componets are registered with the container. (this should be done in subclasses).
68 * <p>
69 * This class also provides a set of static helper method that register 'clusters' of commonly-used components. These
70 * can be called from implementations of component manager to quickly set up the basic parts of the system
71 * @author Noel Winstanley nw@jb.man.ac.uk 04-May-2004
72 * @TODO might be nice to have rather fewer static methods in this design to allow for overriding in subclasses - easier for a component manager to override just a part of the standard setup.
73 * @see org.astrogrid.applications.component.JavaClassCEAComponentManager for example of how to assemble a server using this class.
74 *
75 */
76 public abstract class EmptyCEAComponentManager
77 extends EmptyComponentManager
78 implements CEAComponentManager{
79 /***
80 * Commons Logger for this class
81 */
82 protected static final Log logger = LogFactory
83 .getLog(EmptyCEAComponentManager.class);
84
85 /*** Construct a new EmptyCEAComponentManager
86 *
87 */
88 public EmptyCEAComponentManager() {
89 super();
90 }
91
92 /***
93 * @see org.astrogrid.applications.component.CEAComponentManager#getController()
94 */
95 public final ExecutionController getExecutionController() {
96 return (ExecutionController)this.pico.getComponentInstanceOfType(ExecutionController.class);
97 }
98
99 /***
100 * @see org.astrogrid.applications.component.CEAComponentManager#getMetaData()
101 */
102 public final MetadataService getMetadataService() {
103 return (MetadataService)this.pico.getComponentInstanceOfType(MetadataService.class);
104 }
105
106 public final QueryService getQueryService() {
107 return (QueryService)this.pico.getComponentInstanceOfType(QueryService.class);
108 }
109
110 public final RegistryUploader getRegistryUploaderService() {
111 return (RegistryUploader)this.pico.getComponentInstance(RegistryUploader.class);
112 }
113
114 public final ControlService getControlService() {
115 return (ControlService) this.pico.getComponentInstanceOfType(ControlService.class);
116 }
117
118 public final Configuration getConfiguration() {
119 return (Configuration)this.pico.getComponentInstanceOfType(Configuration.class);
120 }
121
122
123 /*** register the default top-level services core of CEA
124 * registers default implementations of {@link QueryService}, {@link MetadataService} and {@link ExecutionController},
125 * plus the {@link ApplicationDescriptionEnvironment}
126 * also registers a composite application description library, and a container application description library.
127 * @see #registerCompositeApplicationDescriptionLibrary(MutablePicoContainer)
128 * @see #registerContainerApplicationDescriptionLibrary(MutablePicoContainer)
129 * */
130 protected final void registerDefaultServices(MutablePicoContainer pico) {
131 log.debug("Registering default services");
132
133 pico.registerComponentImplementation(ApplicationDescriptionEnvironment.class,ApplicationDescriptionEnvironment.class);
134 pico.registerComponentImplementation(ExecutionController.class,ThreadPoolExecutionController.class);
135 pico.registerComponentImplementation(PooledExecutor.class,CeaThreadPool.class);
136 pico.registerComponentImplementation(QueryService.class,DefaultQueryService.class);
137 registerCompositeApplicationDescriptionLibrary(pico);
138 registerEnvironmentRetriever(pico);
139
140
141 EmptyCEAComponentManager.registerProtocolLibrary(pico);
142 EmptyCEAComponentManager.registerStandardIndirectionProtocols(pico);
143 EmptyCEAComponentManager.registerAstrogridIndirectionProtocols(pico);
144
145
146 this.registerDefaultPersistence(pico, SimpleConfig.getSingleton());
147
148
149 this.registerDefaultVOProvider(pico);
150
151 log.info("Components for a generic CEC have been registered.");
152 }
153
154 /*** registers the default implementaiton of the indirection protocol library
155 * NB: does not register any protocols with the library. These must be added to the container separately
156 * any protocols added to the container wil be detected and added to the library on startup
157 * @see #registerStandardIndirectionProtocols(MutablePicoContainer)
158 * @see #registerAstrogridIndirectionProtocols(MutablePicoContainer)*/
159 protected static final void registerProtocolLibrary(final MutablePicoContainer pico) {
160 log.debug("Registering default indirection protocol library");
161 pico.registerComponentImplementation(ProtocolLibrary.class,DefaultProtocolLibrary.class);
162
163 pico.registerComponentInstance(new Startable() {
164 public void start() {
165 DefaultProtocolLibrary lib = (DefaultProtocolLibrary) pico.getComponentInstanceOfType(DefaultProtocolLibrary.class);
166 for (Iterator i = pico.getComponentAdaptersOfType(Protocol.class).iterator(); i.hasNext(); ) {
167 ComponentAdapter ca = (ComponentAdapter)i.next();
168 Protocol p = (Protocol)ca.getComponentInstance(pico);
169 lib.addProtocol(p);
170 }
171 }
172
173 public void stop() {
174 }
175 });
176 }
177
178 /*** registers the standard indirection protocols - http:, ftp:, file: */
179 protected static final void registerStandardIndirectionProtocols(MutablePicoContainer pico) {
180 pico.registerComponentImplementation(HttpProtocol.class);
181 pico.registerComponentImplementation(FtpProtocol.class);
182 pico.registerComponentImplementation(FileProtocol.class);
183 }
184
185 /*** registers the astorgird-specific protocols - ivo: and agsl:*/
186 protected static final void registerAstrogridIndirectionProtocols(MutablePicoContainer pico) {
187 pico.registerComponentImplementation(IvornProtocol.class);
188 }
189
190 /*** key used to determing from config where to store execution history files
191 * @see #registerDefaultPersistence(MutablePicoContainer, Config) */
192 public static final String FILESTORE_BASEDIR = "cea.filestore.basedir";
193
194 /*** key used to determine which persistence back-end to use -
195 * <br> valid values - <tt>file</tt>, <tt>memory</tt>
196 * <br>optional- defaults to <tt>file</tt>*/
197 public static final String PERSISTENCE_BACKEND = "cea.persistence.backend";
198
199 /*** register the standard persistence system - globally unique id generation, and file-based exection history
200 * configured by {@link #FILESTORE_BASEDIR}
201 * */
202 protected static final void registerDefaultPersistence(MutablePicoContainer pico, final Config config) {
203
204 String backend = System.getProperty(PERSISTENCE_BACKEND,"file").toLowerCase().trim();
205 if (backend.equals("memory")) {
206 log.warn("Only using memory-based persistence system - all history will be lost on restart");
207 pico.registerComponentImplementation(ExecutionHistory.class,InMemoryExecutionHistory.class);
208 } else {
209 if (! backend.equals("file")) {
210 log.error("Unrecognized value '" + backend + "' for key " + PERSISTENCE_BACKEND + " - defaulting to file-based persistence");
211 }
212 log.info("Registering file-based persistence system");
213 pico.registerComponentImplementation(ExecutionHistory.class,FileStoreExecutionHistory.class);
214 }
215 pico.registerComponentImplementation(IdGen.class,GloballyUniqueIdGen.class);
216 }
217
218 /***
219 * key to look in config under for the authorityid to add provided
220 * applications to (optional, defaults to 'org.astrogrid.localhost')
221 *
222 * @see #registerDefaultVOProvider(MutablePicoContainer, Config)
223 */
224 public final static String AUTHORITY_NAME = "cea.application.authorityid";
225
226 /*** register the standard VO Provider - the component that generates the registry entry.
227 * standard provider operates by constructing VODecription from applicationDescriptions in library
228 */
229 protected static final void registerDefaultVOProvider(MutablePicoContainer pico) {
230 log.info("Registering default vo provider - note that this is now the MetadataService");
231 registerVOProvider(pico, DefaultMetadataService.class);
232
233 }
234 /***
235 * @param pico
236 */
237 protected static void registerVOProvider(MutablePicoContainer pico,
238 final Class MetadataServ) {
239
240
241 pico.unregisterComponent(MetadataService.class);
242 pico.unregisterComponent(AppAuthorityIDResolver.class);
243 pico.registerComponentImplementation(MetadataService.class,
244 MetadataServ);
245 pico.registerComponentImplementation(AppAuthorityIDResolver.class,
246 DefaultAppAuthorityIDResolver.class);
247 }
248
249 /*** register optional component that uploads vodescription to registry on startup. */
250 protected static final void registerDefaultRegistryUploader(MutablePicoContainer pico) {
251 log.info("Registering default registry uploader");
252 pico.registerComponentImplementation(RegistryUploader.class);
253 pico.registerComponentImplementation(RegistryAdminLocator.class,
254 RegistryAdminLocatorImpl.class);
255 }
256
257 /*** register the {@link CompositeApplicationDescriptionLibrary} - this will assemble other implementations of {@link ApplicationDescriptionLibrary}
258 * registered in the container into a single unified library - allowing multiple
259 * providers to be merged.
260 * <p/>
261 * For this to work, other app description libs must be registered with pico under their own classname - <b>not</b>
262 * the interface {@link ApplicationDescriptionLIbrary}
263 * @param pico
264 */
265 protected static final void registerCompositeApplicationDescriptionLibrary(final MutablePicoContainer pico) {
266 pico.registerComponentImplementation(ApplicationDescriptionLibrary.class,CompositeApplicationDescriptionLibrary.class);
267
268 pico.registerComponentInstance(new Startable() {
269 public void start() {
270 logger.info("Registering application description libraries in composite");
271 CompositeApplicationDescriptionLibrary uberLib = (CompositeApplicationDescriptionLibrary)pico.getComponentInstanceOfType(CompositeApplicationDescriptionLibrary.class);
272 for (Iterator i = pico.getComponentAdaptersOfType(ApplicationDescriptionLibrary.class).iterator(); i.hasNext(); ) {
273 ComponentAdapter ca = (ComponentAdapter)i.next();
274 ApplicationDescriptionLibrary lib = (ApplicationDescriptionLibrary)ca.getComponentInstance(pico);
275
276 if (lib != uberLib) {
277 uberLib.addLibrary(lib);
278 }
279 }
280 }
281
282 public void stop() {
283 }
284 });
285 }
286 /*** register an {@link ApplicationDescriptionLibrary} that will assemble all {@link ApplicationDescription} components registered with the container
287 * - this allows applicatonDescriptions to be setup and configured individually at the picocontainer level.
288 * @author Noel Winstanley nw@jb.man.ac.uk 05-Jul-2004
289 *
290 */
291 public static void registerContainerApplicationDescriptionLibrary(final MutablePicoContainer pico) {
292 pico.registerComponentImplementation(BaseApplicationDescriptionLibrary.class);
293
294 pico.registerComponentInstance(new Startable() {
295
296 public void start() {
297 BaseApplicationDescriptionLibrary lib = (BaseApplicationDescriptionLibrary)pico.getComponentInstanceOfType(BaseApplicationDescriptionLibrary.class);
298 for (Iterator i = pico.getComponentAdaptersOfType(ApplicationDescription.class).iterator(); i.hasNext();) {
299 ComponentAdapter ca = (ComponentAdapter)i.next();
300 ApplicationDescription appDesc = (ApplicationDescription)ca.getComponentInstance(pico);
301 lib.addApplicationDescription(appDesc);
302 }
303 }
304 public void stop() {
305 }
306 });
307 }
308
309 public void registerEnvironmentRetriever(final MutablePicoContainer pico)
310 {
311 logger.info("registering Default Environment Retriever");
312 pico.registerComponentImplementation(ApplicationEnvironmentRetriver.class, DefaultApplicationEnvironmentRetriever.class);
313 }
314
315
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427