KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > servermgmt > pe > PEInstancesManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.admin.servermgmt.pe;
25
26 import java.util.Map JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.io.File JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30
31 import com.sun.enterprise.util.ProcessExecutor;
32 import com.sun.enterprise.util.SystemPropertyConstants;
33 import com.sun.enterprise.util.io.FileUtils;
34 import com.sun.enterprise.util.i18n.StringManager;
35 import com.sun.enterprise.admin.servermgmt.InstancesManager;
36 import com.sun.enterprise.admin.servermgmt.InstanceException;
37 import com.sun.enterprise.admin.servermgmt.pe.InstanceTimer;
38 import com.sun.enterprise.admin.servermgmt.pe.TimerCallback;
39
40 import com.sun.enterprise.admin.servermgmt.RepositoryConfig;
41 import com.sun.enterprise.admin.servermgmt.RepositoryManager;
42 import com.sun.enterprise.admin.servermgmt.DomainConfig;
43 import com.sun.enterprise.admin.common.Status;
44 import com.sun.enterprise.admin.server.core.channel.RMIClient;
45
46 /**
47  */

48 public class PEInstancesManager extends RepositoryManager implements InstancesManager
49 {
50     /**
51      * i18n strings manager object
52      */

53     private static final StringManager _strMgr =
54         StringManager.getManager(PEInstancesManager.class);
55
56     private final RepositoryConfig _config;
57
58     public PEInstancesManager(RepositoryConfig config)
59     {
60         super();
61         _config = config;
62     }
63
64     protected RepositoryConfig getConfig()
65     {
66         return _config;
67     }
68
69     public void createInstance()
70         throws InstanceException
71     {
72         throw new UnsupportedOperationException JavaDoc(
73             _strMgr.getString("notSupported"));
74     }
75
76     public void deleteInstance() throws InstanceException
77     {
78         throw new UnsupportedOperationException JavaDoc(
79             _strMgr.getString("notSupported"));
80     }
81
82
83     /**
84      * startInstance method to use if there aren't any interactiveOptions or
85      * args to append to the executing process
86      *
87      * @return The Process that is being excecuted
88      * @throws InstanceException
89      */

90     public Process JavaDoc startInstance() throws InstanceException {
91         return startInstance(null, null);
92     }
93
94
95     /**
96      * startInstance method to use if there are interactiveOption, but no
97      * args to append to the executing process
98      *
99      * @param interativeOptions that are passed into the executing process' standard input
100      * @return The Process that is being excecuted
101      * @throws InstanceException
102      */

103     public Process JavaDoc startInstance(String JavaDoc[] interativeOptions) throws InstanceException {
104         String JavaDoc[] commandLineArgs=null;
105         return startInstance(interativeOptions, commandLineArgs);
106     }
107
108
109     /**
110      * startInstance method to use if there are interactiveOption and
111      * args to append to the executing process
112      *
113      * @param interativeOptions that are passed into the executing process' standard input
114      * @param commandLine arguments to be appended to the executing process' commandline
115      * @return The Process that is being excecuted
116      * @throws InstanceException
117      */

118     public Process JavaDoc startInstance(String JavaDoc[] interativeOptions, String JavaDoc[] commandLineArgs)
119         throws InstanceException
120     {
121         preStart();
122
123     // check if --debug or --verbose options were given to asadmin
124
Boolean JavaDoc v = (Boolean JavaDoc)getConfig().get(DomainConfig.K_VERBOSE);
125     boolean verbose = false;
126     if ( v != null ) {
127         verbose = v.booleanValue();
128     }
129
130     Boolean JavaDoc d = (Boolean JavaDoc)getConfig().get(DomainConfig.K_DEBUG);
131         boolean debug = false;
132     if ( d != null ) {
133         debug = d.booleanValue();
134     }
135
136         String JavaDoc[] command=null;
137         File JavaDoc script = getFileLayout(getConfig()).getStartServ();
138         String JavaDoc nativeLauncher=System.getProperty(SystemPropertyConstants.NATIVE_LAUNCHER);
139         Process JavaDoc process=null;
140         ArrayList JavaDoc alCmd=new ArrayList JavaDoc();
141         // append required arguments to start command
142
alCmd.add(script.getAbsolutePath());
143
144         //
145
// add temporary switch for new ProcessLauncher. Will optimize this section
146
// better once the commons-launcher is removed ???
147

148         // This will be removed once PE using the new invocation classes
149
if ( System.getProperty("com.sun.aas.processLauncher") == null && verbose ) {
150         try {
151         // Invoke launcher directly without running startserv script.
152
// This saves a JVM, and will allow CTRL-C and CTRL-\ on asadmin
153
// to reach the server JVM.
154

155         // Set system props needed by launcher
156
System.setProperty(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY,
157                     getConfig().getRepositoryRoot() + File.separator +
158                     getConfig().getRepositoryName());
159         ArrayList JavaDoc args = new ArrayList JavaDoc();
160         args.add("s1as-server");
161                 //FIXTHIS: The com.sun.aas.instanceName probably needs to be dynamically set, but for
162
//now this is not important as it is not being used.
163
args.add("-Dcom.sun.aas.instanceName=server");
164         args.add("start");
165         if ( debug ) {
166             args.add("debug");
167         }
168         if ( verbose ) {
169             args.add("verbose");
170         }
171
172                 // addin command line args
173
if (commandLineArgs != null) {
174                     for(int ii=0; ii < commandLineArgs.length; ii++) {
175                         args.add(commandLineArgs[ii]);
176                     }
177                 }
178
179                 // extract full command
180
String JavaDoc[] argStrings = (String JavaDoc[])args.toArray(
181                     new String JavaDoc[args.size()]);
182
183         /* This doesnt work with the JDK1.4.2 javac
184         LauncherBootstrap.main(argStrings);
185         */

186         Class JavaDoc launcherClass = Class.forName("LauncherBootstrap");
187         Class JavaDoc[] paramClasses = new Class JavaDoc[] { String JavaDoc[].class };
188         Object JavaDoc[] argsArray = new Object JavaDoc[] { argStrings };
189         Method JavaDoc mainMethod = launcherClass.getMethod("main", paramClasses);
190
191         // If verbose, LauncherBootstrap.main() returns only after
192
// the appserver JVM exits.
193
mainMethod.invoke(null, argsArray);
194
195         } catch ( Exception JavaDoc ex ) {
196         throw new InstanceException(
197             getMessages().getInstanceStartupExceptionMessage(
198             getConfig().getDisplayName()), ex);
199         }
200
201     } else if (System.getProperty("com.sun.aas.processLauncher") != null && verbose) {
202         // add arguments to main command, native must come first
203
if (nativeLauncher != null && nativeLauncher.equals("true")) {
204             // use native launcher, add in argument
205
alCmd.add("native");
206         }
207         if (debug) alCmd.add("debug");
208         if (verbose) alCmd.add("verbose");
209         // addin command line args
210
if (commandLineArgs != null) {
211             for(int ii=0; ii < commandLineArgs.length; ii++) {
212                 alCmd.add(commandLineArgs[ii]);
213             }
214         }
215
216         // extract full command
217
command=new String JavaDoc[alCmd.size()];
218         command=(String JavaDoc[])alCmd.toArray(command);
219
220         try {
221             // exec process directly to exercise needed control
222
ProcessExecutor exec = new ProcessExecutor(command, interativeOptions);
223             // set verbose flag so process error stream get redirected to stderr
224
exec.setVerbose(verbose);
225             // call execute so it will not be timed out
226
exec.execute(false, false);
227             process=exec.getSubProcess();
228             // this will force process to wait for executing process
229
int exitValue=process.waitFor();
230             System.exit(exitValue);
231         } catch (Exception JavaDoc e) {
232             throw new InstanceException(_strMgr.getString("procExecError"), e);
233         }
234
235     } else {
236         // add arguments to main command, native must come first
237
if (nativeLauncher != null && nativeLauncher.equals("true")) {
238             // use native launcher, add in argument
239
alCmd.add("native");
240         }
241
242         // check to see if debug is enabled
243
if (debug) {
244             alCmd.add("debug");
245         }
246
247         // addin command line args
248
if (commandLineArgs != null) {
249             for(int ii=0; ii < commandLineArgs.length; ii++) {
250                 alCmd.add(commandLineArgs[ii]);
251             }
252         }
253
254         // extract full command
255
command=new String JavaDoc[alCmd.size()];
256         command=(String JavaDoc[])alCmd.toArray(command);
257
258         // call method for executing so can be overriden in descendants
259
// also, keep executor for any error information
260
ProcessExecutor processExec=startInstanceExecute(command, interativeOptions);
261         process=processExec.getSubProcess();
262         waitUntilStarting(processExec);
263         waitUntilStarted();
264         postStart();
265     }
266
267         return process;
268     }
269
270     /**
271     * This method is called internally from the startInstance method
272     * and was needed so SE could execute a process that doesn't return
273     */

274     protected ProcessExecutor startInstanceExecute(String JavaDoc[] command, String JavaDoc[] interativeOptions) throws InstanceException {
275         return execute(command, interativeOptions);
276     }
277
278
279
280     public void stopInstance() throws InstanceException
281     {
282         preStop();
283         execute(getFileLayout(getConfig()).getStopServ());
284         waitUntilStopped();
285         postStop();
286     }
287
288     public String JavaDoc[] listInstances() throws InstanceException
289     {
290         throw new UnsupportedOperationException JavaDoc(
291             _strMgr.getString("notSupported"));
292     }
293
294     public boolean isInstanceStarting() throws InstanceException
295     {
296         return (getInstanceStatus() ==
297              Status.kInstanceStartingCode);
298     }
299
300     public boolean isInstanceRunning() throws InstanceException
301     {
302         return (Status.kInstanceRunningCode ==
303                 getInstanceStatus());
304     }
305
306     /**
307      * Returns whether the server is in the startup failed state or
308      * not.
309      */

310     public boolean isInstanceFailed() throws InstanceException
311     {
312         return (Status.kInstanceFailedCode ==
313                 getInstanceStatus());
314     }
315
316     public boolean isInstanceNotRunning() throws InstanceException
317     {
318         return (Status.kInstanceNotRunningCode ==
319                 getInstanceStatus());
320     }
321
322     public boolean isRestartNeeded() throws InstanceException
323     {
324         boolean isRestartNeeded = false;
325         try
326         {
327             isRestartNeeded = getRMIClient().isRestartNeeded();
328         }
329         catch (Exception JavaDoc e)
330         {
331             throw new InstanceException(e.getMessage(), e);
332         }
333         return isRestartNeeded;
334     }
335
336     /**
337         To start an instance the instance must be in not running state.
338      */

339     protected void preStart() throws InstanceException
340     {
341         final int state = getInstanceStatus();
342         if (Status.kInstanceNotRunningCode != state)
343         {
344             throw new InstanceException(
345                 getMessages().getCannotStartInstanceInvalidStateMessage(
346                     getConfig().getDisplayName(),
347                     Status.getStatusString(state)));
348         }
349     }
350
351     void postStart() throws InstanceException
352     {
353         if (isInstanceFailed()) {
354             int port = getConflictedPort();
355             abortServer();
356             throw new InstanceException(
357                 getMessages().getStartupFailedMessage(
358                     getConfig().getDisplayName(), port ));
359         }
360         if (!isInstanceRunning() &&
361             !isInstanceNotRunning())
362         {
363             /*
364                 Instance could not be started in TIME_OUT_SECONDS.
365                 Trying to stop.
366              */

367             try {
368                 stopInstance();
369             } catch (Exception JavaDoc e) {
370                 throw new InstanceException(
371                     getMessages().getStartInstanceTimeOutMessage(
372                         getConfig().getDisplayName()), e);
373             }
374             throw new InstanceException(
375                getMessages().getStartInstanceTimeOutMessage(
376                    getConfig().getDisplayName()));
377         }
378         if (isInstanceNotRunning()) {
379             throw new InstanceException(
380                 getMessages().getStartupFailedMessage(
381                     getConfig().getDisplayName()));
382         }
383         setRMIClient(null);
384     }
385
386     /**
387         To stop an instance the instance must be in (running | stopping |
388         starting) state.
389      */

390     void preStop() throws InstanceException
391     {
392         final int state = getInstanceStatus();
393         /*
394         if (!((state == Status.kInstanceRunningCode) ||
395               (state == Status.kInstanceStoppingCode) ||
396               (state == Status.kInstanceStartingCode)))
397          */

398         //For now we can only allow running instances to be stopped. Stopping the
399
//node agent while it is starting is a bad idea.
400
if (state != Status.kInstanceRunningCode)
401         {
402             throw new InstanceException(
403                 getMessages().getCannotStopInstanceInvalidStateMessage(
404                     getConfig().getDisplayName(),
405                     Status.getStatusString(state)));
406         }
407     }
408
409     void postStop() throws InstanceException
410     {
411         if (!isInstanceNotRunning())
412         {
413             throw new InstanceException(
414                 getMessages().getCannotStopInstanceMessage(
415                     getConfig().getDisplayName()));
416         }
417         setRMIClient(null);
418     }
419
420
421     // method to over ride timeout time for server to go to starting state
422
// This value should be configurable by end user ???
423
protected void waitUntilStarting(ProcessExecutor processExec) throws InstanceException
424     {
425         waitUntilStarting(processExec, 180);
426     }
427
428     protected void waitUntilStarting(ProcessExecutor processExec, int timeoutSeconds) throws InstanceException
429     {
430         InstanceTimer timer = new InstanceTimer(timeoutSeconds, 0,
431             new TimerCallback()
432             {
433                 public boolean check() throws Exception JavaDoc
434                 {
435                     return isInstanceStarting() ||
436                            isInstanceRunning() ||
437                            isInstanceFailed();
438                 }
439             }
440         );
441         timer.run(); //synchronous
442

443
444         if (getInstanceStatus() == Status.kInstanceNotRunningCode)
445         {
446             throw new InstanceException(
447                 getMessages().getTimeoutStartingMessage(
448                     getConfig().getDisplayName()));
449         }
450     }
451
452     // method to over ride timeout time for server to started state
453
// Also this value should be configurable by end user ???
454
protected void waitUntilStarted() throws InstanceException
455     {
456         // PE set to 20 minutes
457
waitUntilStarted(1200);
458     }
459
460
461     protected void waitUntilStarted(int timeoutSeconds) throws InstanceException
462     {
463         InstanceTimer timer = new InstanceTimer(timeoutSeconds, 0,
464             new TimerCallback()
465             {
466                 public boolean check() throws Exception JavaDoc
467                 {
468                     return (isInstanceRunning() ||
469                             isInstanceFailed() ||
470                             isInstanceNotRunning());
471                 }
472             }
473         );
474         timer.run(); //synchronous
475
}
476
477     void waitUntilStopped() throws InstanceException
478     {
479         final int timeOutSeconds = 60;
480         InstanceTimer timer = new InstanceTimer(timeOutSeconds, 0,
481             new TimerCallback()
482             {
483                 public boolean check() throws Exception JavaDoc
484                 {
485                     return isInstanceNotRunning();
486                 }
487             }
488         );
489         timer.run(); //synchronous
490
}
491
492     void execute(File JavaDoc script) throws InstanceException
493     {
494         try
495         {
496             ProcessExecutor exec = new ProcessExecutor(
497                                    new String JavaDoc[] {script.getAbsolutePath()});
498             exec.execute();
499         }
500         catch (Exception JavaDoc e)
501         {
502             throw new InstanceException(_strMgr.getString("procExecError"), e);
503         }
504     }
505
506     ProcessExecutor execute(String JavaDoc[] command) throws InstanceException {
507         return execute(command, null);
508     }
509
510     ProcessExecutor execute(String JavaDoc[] command, String JavaDoc[] interativeOptions) throws InstanceException
511     {
512         try
513         {
514             ProcessExecutor exec = new ProcessExecutor(command, interativeOptions);
515             String JavaDoc nativeLauncher=System.getProperty(SystemPropertyConstants.NATIVE_LAUNCHER);
516             if (nativeLauncher != null && nativeLauncher.equals("true")) {
517                 // native processes don't return, so don't wait
518
// this follows the methodology for se, but should be revisted to make
519
// sure timeouts for state transitions are reasonable
520
exec.execute(false, false);
521             } else {
522                 // expect the process to return
523
exec.execute();
524             }
525
526
527             // this signature for execute will terminiate the process
528
// if it goes on too long, reason for return signature is for SE ProcessManager watchdog
529
return exec;
530         }
531         catch (Exception JavaDoc e)
532         {
533             throw new InstanceException(_strMgr.getString("procExecError"), e);
534         }
535     }
536
537     protected PEFileLayout getFileLayout()
538     {
539         return super.getFileLayout(getConfig());
540     }
541
542     /**
543      * Get the port on which conflict occured.
544      */

545     int getConflictedPort() {
546         int port = 0;
547         try {
548             port = getRMIClient().getConflictedPort();
549         }
550         catch (Exception JavaDoc ex) {
551             // Not interested!!
552
}
553         return port;
554     }
555
556     /**
557      * AS PE will wait before exiting, until client executes this method.
558      */

559     void abortServer() {
560         try {
561             getRMIClient().triggerServerExit();
562         }
563         catch (Throwable JavaDoc t) {
564             //Even if there is an error, that should not affect client performance.
565
//Ignore the error.
566
}
567     }
568
569     public int getInstanceStatus() throws InstanceException
570     {
571         int status = Integer.MIN_VALUE;
572         try {
573             status = getRMIClient().getInstanceStatusCode();
574         }
575         catch (Exception JavaDoc ex) {
576             /**
577              * There is a timimg issue here while reading the admsn file.
578              * If the client attempts to rmi the server before the admsn
579              * is created an exception will be thrown. Supressing the exception
580              * so that the client will be able to rmi the server in the next
581              * attempt once the admsn was created.
582              */

583             //throw new InstanceException(ex);
584
//log this??
585
}
586         return status;
587     }
588
589     private RMIClient rmiClient = null;
590
591     private RMIClient getRMIClient()
592     {
593         if (rmiClient == null)
594         {
595             String JavaDoc stubPath = getFileLayout().getStubFile().getAbsolutePath();
596             String JavaDoc seedPath = getFileLayout().getSeedFile().getAbsolutePath();
597             rmiClient = new RMIClient(false, stubPath, seedPath);
598         }
599         return rmiClient;
600     }
601
602     private void setRMIClient(RMIClient client)
603     {
604         this.rmiClient = client;
605     }
606 }
607
Popular Tags