KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > jbi > management > systemstate > SystemRecovery


1 /**
2  * PETALS - PETALS Services Platform.
3  * Copyright (c) 2006 EBM Websourcing, http://www.ebmwebsourcing.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * -------------------------------------------------------------------------
19  * $Id: SystemRecovery.java 154 2 mai 2006 ofabre $
20  * -------------------------------------------------------------------------
21  */

22 package org.objectweb.petals.jbi.management.systemstate;
23
24 import java.io.File JavaDoc;
25 import java.net.URI JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.List JavaDoc;
30
31 import javax.jbi.JBIException;
32 import javax.jbi.management.LifeCycleMBean;
33 import javax.management.InstanceNotFoundException JavaDoc;
34 import javax.management.MBeanException JavaDoc;
35 import javax.management.MBeanServer JavaDoc;
36 import javax.management.ObjectName JavaDoc;
37 import javax.management.ReflectionException JavaDoc;
38
39 import org.objectweb.petals.PetalsException;
40 import org.objectweb.petals.jbi.component.lifecycle.Installer;
41 import org.objectweb.petals.jbi.component.lifecycle.ServiceAssemblyLifeCycle;
42 import org.objectweb.petals.jbi.management.deployment.DeploymentContextConstants;
43 import org.objectweb.petals.jbi.management.deployment.DeploymentService;
44 import org.objectweb.petals.jbi.management.deployment.DeploymentTaskFactory;
45 import org.objectweb.petals.jbi.management.service.InstallationService;
46 import org.objectweb.petals.jbi.management.service.LifeCycleManagerService;
47 import org.objectweb.petals.jbi.management.service.ManagementException;
48 import org.objectweb.petals.jbi.management.service.PackageHandler;
49 import org.objectweb.petals.processor.TaskProcessor;
50 import org.objectweb.petals.repository.RepositoryService;
51 import org.objectweb.petals.tools.jbicommon.descriptor.JBIDescriptor;
52 import org.objectweb.petals.util.LoggingUtil;
53 import org.objectweb.util.monolog.api.Logger;
54
55 /**
56  * Allows to restore system state after shutdown or crash.
57  *
58  * @author Olivier Fabre - EBM Websourcing
59  *
60  */

61 public class SystemRecovery {
62
63     protected DeploymentService deploymentService;
64
65     protected InstallationService installationService;
66
67     protected LoggingUtil log;
68
69     protected LifeCycleManagerService managerService;
70
71     protected PackageHandler packageHandler;
72
73     protected RepositoryService repositorySrv;
74
75     protected StateStorage stateStorage;
76
77     public SystemRecovery(InstallationService installationService,
78             Logger logger, DeploymentService deploymentService,
79             LifeCycleManagerService managerService, StateStorage stateStorage,
80             RepositoryService repositorySrv) {
81         super();
82         this.deploymentService = deploymentService;
83         this.installationService = installationService;
84         this.managerService = managerService;
85         this.log = new LoggingUtil(logger);
86         this.stateStorage = stateStorage;
87         this.repositorySrv = repositorySrv;
88         this.packageHandler = new PackageHandler(logger, repositorySrv);
89         createLostPlusFoundDir();
90         createRepositoryDirectories();
91     }
92
93     protected void createRepositoryDirectories() {
94         File JavaDoc componentsRep = new File JavaDoc(repositorySrv.getComponentsDirectory());
95         File JavaDoc serviceAssRep = new File JavaDoc(repositorySrv
96                 .getServiceAssembliesDirectory());
97         File JavaDoc sharedLibRep = new File JavaDoc(repositorySrv.getSharedLibsDirectory());
98
99         // Create components directory in Petals repository if it doesn't exist
100
if (!componentsRep.exists()) {
101             if (!componentsRep.mkdirs()) {
102                 String JavaDoc msg = "Failed to create components dir in Petals repository";
103                 log.error(msg);
104                 throw new RuntimeException JavaDoc(msg);
105             }
106         }
107
108         // Create sharedlibs directory in Petals repository if it doesn't exist
109
if (!sharedLibRep.exists()) {
110             if (!sharedLibRep.mkdirs()) {
111                 String JavaDoc msg = "Failed to create sharedlibs dir in Petals repository";
112                 log.error(msg);
113                 throw new RuntimeException JavaDoc(msg);
114             }
115         }
116
117         // Create serviceassemblies directory in Petals repository if it doesn't
118
// exist
119
if (!serviceAssRep.exists()) {
120             if (!serviceAssRep.mkdirs()) {
121                 String JavaDoc msg = "Failed to create serviceassemblies dir in Petals repository";
122                 log.error(msg);
123                 throw new RuntimeException JavaDoc(msg);
124             }
125         }
126     }
127
128     public boolean recoverAllComponent() throws ManagementException {
129         log.start();
130         String JavaDoc msg = null;
131
132         /*
133          * Retrieve all component directories in the components petals
134          * repository. This list will be used to delete components that have
135          * been unzipped in the Petals repository but no more persisted in the
136          * system recory file (system-state.xml). These unknown component
137          * directories will be put in the Petals "lost+found" directory.
138          */

139
140         List JavaDoc<File JavaDoc> unknownDirs = new ArrayList JavaDoc<File JavaDoc>(Arrays.asList(new File JavaDoc(
141                 repositorySrv.getComponentsDirectory()).listFiles()));
142
143         /*
144          * Retrieve all components to recover
145          */

146
147         List JavaDoc<ComponentState> cps = stateStorage.retrieveAllComponentStates();
148
149         /*
150          * Recover state for each component
151          */

152         for (ComponentState state : cps) {
153
154             URI JavaDoc installationRoot = null;
155             try {
156
157                 installationRoot = packageHandler.processAndGetPackageURI(state
158                         .getInstallURL(), true);
159
160                 URI JavaDoc archiveURI = packageHandler.processAndGetPackageURI(state
161                         .getArchiveURL(), true);
162
163                 JBIDescriptor descriptor = packageHandler
164                         .loadDescriptor(archiveURI);
165
166                 recoverComponent(installationRoot, descriptor, state
167                         .getInstallState(), state.getLifecycleState());
168             } catch (PetalsException e) {
169                 msg = "A component can't be recovered : " + state.getName();
170                 log.error(msg, e);
171                 throw new ManagementException(msg, e);
172             }
173
174             // Delete component from the unknownDirs list because this
175
// component is known now...
176
if (unknownDirs != null) {
177                 File JavaDoc knownComp = new File JavaDoc(installationRoot).getParentFile();
178                 if (knownComp.exists()) {
179                     unknownDirs.remove(knownComp);
180                 }
181             }
182         }
183
184         // Now, move all unknown components from Petals repository to
185
// "lost+found" dir
186
moveUnknownDirsToLostPlusFoundDir(unknownDirs);
187
188         log.end();
189         return false;
190     }
191
192     public boolean recoverAllServiceAssembly() throws ManagementException {
193         log.start();
194         String JavaDoc msg = null;
195
196         /*
197          * Retrieve all sa directories in the sa petals repository. This list
198          * will be used to delete sa that have been unzipped in the Petals
199          * repository but no more persisted in the system recory file
200          * (system-state.xml). These unknown sa directories will be put in the
201          * Petals "lost+found" directory.
202          */

203
204         List JavaDoc<File JavaDoc> unknownDirs = new ArrayList JavaDoc<File JavaDoc>(Arrays.asList(new File JavaDoc(
205                 repositorySrv.getServiceAssembliesDirectory()).listFiles()));
206
207         /*
208          * Retrieve all service assemblies to recover
209          */

210
211         List JavaDoc<ServiceAssemblyState> sas = stateStorage
212                 .retrieveAllServiceAssemblyStates();
213
214         /*
215          * Recover state for each service assembly
216          */

217
218         for (ServiceAssemblyState state : sas) {
219             URI JavaDoc installationRoot = null;
220             try {
221
222                 installationRoot = packageHandler.processAndGetPackageURI(state
223                         .getInstallURL(), true);
224
225                 URI JavaDoc archiveURI = packageHandler.processAndGetPackageURI(state
226                         .getArchiveURL(), true);
227
228                 JBIDescriptor descriptor = packageHandler
229                         .loadDescriptor(archiveURI);
230
231                 recoverServiceAssembly(archiveURI, descriptor, state
232                         .getLifecycleState());
233             } catch (PetalsException e) {
234                 msg = "A service assembly can't be recovered : "
235                         + state.getName();
236                 log.error(msg, e);
237                 throw new ManagementException(msg, e);
238             } catch (Exception JavaDoc e) {
239                 msg = "A service assembly can't be recovered : "
240                         + state.getName();
241                 log.error(msg, e);
242                 throw new ManagementException(msg, e);
243             }
244
245             // Delete sa from the unknownDirs list because this
246
// sa is known now...
247
if (unknownDirs != null) {
248                 File JavaDoc knownComp = new File JavaDoc(installationRoot).getParentFile();
249                 if (knownComp.exists()) {
250                     unknownDirs.remove(knownComp);
251                 }
252             }
253         }
254
255         // Now, move all unknown sl from Petals repository to
256
// "lost+found" dir
257
moveUnknownDirsToLostPlusFoundDir(unknownDirs);
258
259         log.end();
260         return false;
261     }
262
263     public boolean recoverAllSharedLibrary() throws ManagementException {
264         log.start();
265         String JavaDoc msg = null;
266
267         /*
268          * Retrieve all sl directories in the sl petals repository. This list
269          * will be used to delete sl that have been unzipped in the Petals
270          * repository but no more persisted in the system recory file
271          * (system-state.xml). These unknown sl directories will be put in the
272          * Petals "lost+found" directory.
273          */

274
275         List JavaDoc<File JavaDoc> unknownDirs = new ArrayList JavaDoc<File JavaDoc>(Arrays.asList(new File JavaDoc(
276                 repositorySrv.getSharedLibsDirectory()).listFiles()));
277
278         /*
279          * Retrieve all shared library to recover
280          */

281
282         List JavaDoc<SharedLibraryState> sls = stateStorage
283                 .retrieveAllSharedLibraryStates();
284
285         /*
286          * Recover state for each shared library
287          */

288         for (SharedLibraryState state : sls) {
289             URI JavaDoc installationRoot = null;
290             try {
291
292                 installationRoot = packageHandler.processAndGetPackageURI(state
293                         .getInstallURL(), true);
294
295                 URI JavaDoc archiveURI = packageHandler.processAndGetPackageURI(state
296                         .getArchiveURL(), true);
297
298                 JBIDescriptor descriptor = packageHandler
299                         .loadDescriptor(archiveURI);
300
301                 recoverSharedLib(installationRoot, descriptor);
302             } catch (PetalsException e) {
303                 msg = "A Shared lib can't be recovered : " + state.getName();
304                 log.error(msg, e);
305                 throw new ManagementException(msg, e);
306             }
307
308             // Delete sl from the unknownDirs list because this
309
// sl is known now...
310
if (unknownDirs != null) {
311                 File JavaDoc knownComp = new File JavaDoc(installationRoot).getParentFile();
312                 if (knownComp.exists()) {
313                     unknownDirs.remove(knownComp);
314                 }
315             }
316         }
317
318         // Now, move all unknown sl from Petals repository to
319
// "lost+found" dir
320
moveUnknownDirsToLostPlusFoundDir(unknownDirs);
321
322         log.end();
323         return false;
324     }
325
326     /**
327      * Create the lost+found dir in the petals file system if it doesn't exist,
328      * and cleanup it if it exists
329      *
330      */

331     protected void createLostPlusFoundDir() {
332         File JavaDoc lostPlusFoundFile = new File JavaDoc(repositorySrv
333                 .getLostPlusFoundDirectory());
334         // Cleanup lost+found directory at Petals startup
335
if (lostPlusFoundFile.exists()) {
336             if (!lostPlusFoundFile.delete()) {
337                 log
338                         .warning("\"lost+found\" can't be deleted, "
339                                 + "following Petals repository cleanup can have some troubles!");
340             } else {
341                 if (!lostPlusFoundFile.mkdirs()) {
342                     String JavaDoc msg = "Failed to create lost+found directory, "
343                             + "following Petals repository cleanup will fail!";
344                     log.warning(msg);
345                 }
346             }
347         } else {
348             if (!lostPlusFoundFile.mkdirs()) {
349                 String JavaDoc msg = "Failed to create lost+found directory, "
350                         + "following Petals repository cleanup will fail!";
351                 log.warning(msg);
352             }
353         }
354     }
355
356     /**
357      * Move all unknown components from Petals repository to "lost+found" dir
358      *
359      * @param unknownDirs
360      * the {@link List} of unknown dirs that have to be moved.
361      */

362     protected void moveUnknownDirsToLostPlusFoundDir(List JavaDoc<File JavaDoc> unknownDirs) {
363         if (unknownDirs != null) {
364             for (File JavaDoc unknownDir : unknownDirs) {
365
366                 if (!unknownDir.exists()) {
367                     log
368                             .warning("The unknown dir ("
369                                     + unknownDir.getAbsolutePath()
370                                     + ") doesn't exist.");
371                 }
372                 boolean moveDir = unknownDir.renameTo(new File JavaDoc(new File JavaDoc(
373                         repositorySrv.getLostPlusFoundDirectory()), unknownDir
374                         .getName()));
375                 if (!moveDir) {
376                     log.warning("Failed to move unknown directory ("
377                             + unknownDir.getAbsolutePath()
378                             + ") to lost+found directory");
379                 }
380             }
381         }
382     }
383
384     /**
385      * Recover the given component. Recovering a component consist in redoing
386      * installation process of a component (see <code>InstallationService</code>),
387      * calling the "install" method on the created Installer and putting the
388      * component in its previous state by calling "start" or/and "stop" on the
389      * created component lifecycle.
390      *
391      * @param installationRoot
392      * @param archiveURI
393      * @param installState
394      * @param lifecycleState
395      * @throws ManagementException
396      */

397     protected void recoverComponent(URI JavaDoc installationRoot,
398             JBIDescriptor descriptor, String JavaDoc installState, String JavaDoc lifecycleState)
399         throws ManagementException {
400         log.start();
401         String JavaDoc msg = null;
402
403         String JavaDoc compName = descriptor.getComponent().getIdentification()
404                 .getName();
405         try {
406
407             if (Installer.INSTALLED.equals(installState)) {
408                 /*
409                  * Redo install
410                  */

411                 ObjectName JavaDoc installerName = installationService
412                         .loadNewInstaller(installationRoot, descriptor);
413                 MBeanServer JavaDoc beanServer = managerService.getMBeanServer();
414
415                 Object JavaDoc[] nullObjects = new Object JavaDoc[0];
416                 String JavaDoc[] nullStrings = new String JavaDoc[0];
417                 ObjectName JavaDoc clcName = (ObjectName JavaDoc) beanServer.invoke(
418                         installerName, "install", nullObjects, nullStrings);
419
420                 if (LifeCycleMBean.STOPPED.equals(lifecycleState)) {
421                     /*
422                      * Redo start followed by stop
423                      */

424                     beanServer.invoke(clcName, "start", nullObjects,
425                             nullStrings);
426                     beanServer
427                             .invoke(clcName, "stop", nullObjects, nullStrings);
428                 } else if (LifeCycleMBean.STARTED.equals(lifecycleState)) {
429                     /*
430                      * Redo start
431                      */

432                     beanServer.invoke(clcName, "start", nullObjects,
433                             nullStrings);
434                 }
435             }
436         } catch (InstanceNotFoundException JavaDoc e) {
437             msg = "Component can't be recovered : " + compName;
438             log.error(msg, e);
439             throw new ManagementException(msg, e);
440         } catch (MBeanException JavaDoc e) {
441             msg = "Component can't be recovered : " + compName;
442             log.error(msg, e);
443             throw new ManagementException(msg, e);
444         } catch (ReflectionException JavaDoc e) {
445             msg = "Component can't be recovered : " + compName;
446             log.error(msg, e);
447             throw new ManagementException(msg, e);
448         } catch (PetalsException e) {
449             msg = "Component can't be recovered : " + compName;
450             log.error(msg, e);
451             throw new ManagementException(msg, e);
452         }
453         log.end();
454     }
455
456     /**
457      * Recover the given Service Assembly. Recovering a Service Assembly consist
458      * in redoing deployment process of a Service Assembly (see
459      * <code>DeploymentService</code>) and putting the Service Assembly in
460      * its previous state by calling "start" or/and "stop" on the created
461      * component lifecycle.
462      *
463      * @param installationRoot
464      * @param archiveURI
465      * @param lifecycleState
466      * @throws ManagementException
467      */

468     protected void recoverServiceAssembly(URI JavaDoc archiveURI,
469             JBIDescriptor descriptor, String JavaDoc lifecycleState) throws Exception JavaDoc {
470         log.start();
471         String JavaDoc msg = null;
472
473         String JavaDoc saName = descriptor.getServiceAssembly().getIdentification()
474                 .getName();
475         try {
476
477             /*
478              * Redo deployment
479              */

480
481             // Create deployment execution context
482
HashMap JavaDoc<String JavaDoc, Object JavaDoc> deploymentContext = createDeploymentContext(
483                     archiveURI, descriptor);
484
485             // Create deployment processor and fill with tasks
486
TaskProcessor processor = createDeploymentProcessor(deploymentContext);
487
488             // Launch the process
489
if (!processor.process()) {
490                 msg = "An error occured during the deployment "
491                         + "of the following service assembly: "
492                         + saName;
493                 throw new Exception JavaDoc(msg);
494             }
495
496             if (LifeCycleMBean.STOPPED.equals(lifecycleState)) {
497                 /*
498                  * Redo start followed by stop
499                  */

500                 ServiceAssemblyLifeCycle salc = managerService
501                         .getServiceAssemblyByName(saName);
502                 salc.start();
503                 salc.stop();
504             } else if (LifeCycleMBean.STARTED.equals(lifecycleState)) {
505                 /*
506                  * Redo start
507                  */

508                 ServiceAssemblyLifeCycle salc = managerService
509                         .getServiceAssemblyByName(saName);
510                 salc.start();
511             }
512
513         } catch (PetalsException e) {
514             msg = "ServiceAssembly can't be recovered : " + saName;
515             log.error(msg, e);
516             throw new ManagementException(msg, e);
517         } catch (JBIException e) {
518             msg = "ServiceAssembly can't be recovered : " + saName;
519             log.error(msg, e);
520             throw new ManagementException(msg, e);
521         }
522         log.end();
523     }
524
525     /**
526      * Create the deployment processor and add all required task for the
527      * complete deployment of a service assembly
528      *
529      * @param deploymentContext
530      * the deployment context
531      * @return the filled deployment processor
532      */

533     protected TaskProcessor createDeploymentProcessor(
534             HashMap JavaDoc<String JavaDoc, Object JavaDoc> deploymentContext) {
535         TaskProcessor processor = new TaskProcessor(deploymentContext, log);
536
537         DeploymentTaskFactory deploymentTaskFactory = deploymentService
538                 .getDeploymentTaskFactory();
539
540         processor.addTask(deploymentTaskFactory.getPackageCheckingTask());
541         processor.addTask(deploymentTaskFactory.getResultCreationTask());
542         processor.addTask(deploymentTaskFactory
543                 .getSaAndSUInstallRootRetrievalTask());
544         processor.addTask(deploymentTaskFactory.getAllSUDeploymentTask());
545         processor.addTask(deploymentTaskFactory
546                 .getSaLifeCycleRegistrationTask());
547         processor.addTask(deploymentTaskFactory
548                 .getAllConnectionRegistrationTask());
549         processor.addTask(deploymentTaskFactory.getDeploymentSuccessTask());
550
551         return processor;
552     }
553
554     /**
555      * Create the deployment context
556      *
557      * @param archiveURI
558      * the sa archive URI
559      * @param descriptor
560      * the sa jbi descriptor
561      * @return the Deployment Context HashMap
562      */

563     protected HashMap JavaDoc<String JavaDoc, Object JavaDoc> createDeploymentContext(URI JavaDoc archiveURI,
564             JBIDescriptor descriptor) {
565         HashMap JavaDoc<String JavaDoc, Object JavaDoc> deploymentContext = new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
566         deploymentContext.put(DeploymentContextConstants.ARCHIVE_URI,
567                 archiveURI);
568         deploymentContext.put(DeploymentContextConstants.SA_DESCRIPTOR,
569                 descriptor);
570         return deploymentContext;
571     }
572
573     /**
574      * Recover the given shared library. Recovering a shared lib consist in
575      * redoing installation process of a shared lib (see
576      * <code>InstallationService</code>).
577      *
578      * @param installationRoot
579      * @param archiveURI
580      * @throws ManagementException
581      */

582     protected void recoverSharedLib(URI JavaDoc installationRoot,
583             JBIDescriptor descriptor) throws ManagementException {
584         log.start();
585
586         /*
587          * Redo install
588          */

589         try {
590             installationService.installSharedLibrary(installationRoot,
591                     descriptor);
592         } catch (PetalsException e) {
593             String JavaDoc msg = "ServiceAssembly can't be recovered : "
594                     + installationRoot.toString();
595             log.error(msg, e);
596             throw new ManagementException(msg, e);
597         }
598
599         log.end();
600     }
601
602 }
603
Popular Tags