KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > server > core > mbean > config > ServerController


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.server.core.mbean.config;
25
26 //iAS imports
27
import com.sun.enterprise.instance.ServerManager;
28 import com.sun.enterprise.instance.InstanceDefinition;
29 import com.sun.enterprise.instance.InstanceEnvironment;
30 import com.sun.enterprise.config.ConfigException;
31 import com.sun.enterprise.config.ConfigFactory;
32 import com.sun.enterprise.config.ConfigContext;
33 import com.sun.enterprise.config.ConfigBeansFactory;
34 import com.sun.enterprise.config.serverbeans.JavaConfig;
35 import com.sun.enterprise.config.serverbeans.JmsService;
36 import com.sun.enterprise.config.serverbeans.ServerXPathHelper;
37 import com.sun.enterprise.util.ProcessExecutor;
38 import com.sun.enterprise.util.ExecException;
39 import com.sun.enterprise.util.io.FileUtils;
40
41 // JMS Provider/MQ related imports
42
import com.sun.enterprise.jms.IASJmsUtil;
43 import com.sun.messaging.jmq.jmsspi.JMSAdmin;
44
45 //Admin imports
46
import com.sun.enterprise.admin.util.ArgChecker;
47 import com.sun.enterprise.admin.util.StringValidator;
48 import com.sun.enterprise.admin.util.HostAndPort;
49 import com.sun.enterprise.admin.common.OperationProgress;
50 import com.sun.enterprise.admin.common.ServerInstanceStatus;
51 import com.sun.enterprise.admin.common.RequestID;
52 import com.sun.enterprise.admin.common.exception.InstanceAlreadyExistsException;
53 import com.sun.enterprise.admin.common.exception.NoSuchInstanceException;
54 import com.sun.enterprise.admin.common.exception.ControlException;
55 import com.sun.enterprise.admin.common.ByteChunk;
56 import com.sun.enterprise.admin.common.ObjectNames;
57 import com.sun.enterprise.admin.common.ObjectNameHelper;
58 import com.sun.enterprise.admin.common.MBeanServerFactory;
59 import com.sun.enterprise.admin.common.constant.AdminConstants;
60 import com.sun.enterprise.admin.server.core.mbean.meta.MBeanEasyConfig;
61 import com.sun.enterprise.admin.server.core.AdminService;
62
63 //Channel related
64
import com.sun.enterprise.admin.server.core.channel.AdminChannel;
65 import com.sun.enterprise.admin.server.core.channel.RMIClient;
66
67 //JDK imports
68
import java.io.File JavaDoc;
69 import java.io.FileOutputStream JavaDoc;
70 import java.io.OutputStream JavaDoc;
71 import java.io.IOException JavaDoc;
72 import java.io.FileNotFoundException JavaDoc;
73 import java.util.Hashtable JavaDoc;
74 import java.util.Iterator JavaDoc;
75 import java.util.Vector JavaDoc;
76 import java.io.RandomAccessFile JavaDoc;
77 import java.util.logging.Level JavaDoc;
78 import java.util.logging.Logger JavaDoc;
79
80 //JMX imports
81
import javax.management.ObjectName JavaDoc;
82 import javax.management.MBeanServer JavaDoc;
83 import javax.management.MBeanInfo JavaDoc;
84
85 //Other imports
86
import com.sun.appserv.server.util.Version;
87 import com.sun.enterprise.admin.AdminContext;
88 import com.sun.enterprise.admin.common.domains.registry.DomainEntry;
89 import com.sun.enterprise.admin.common.domains.registry.DomainRegistry;
90 //import com.sun.enterprise.admin.verifier.tests.StaticTest;
91

92 //i18n import
93
import com.sun.enterprise.util.i18n.StringManager;
94 import com.sun.enterprise.util.RelativePathResolver;
95
96 /**
97     A managed Controller of the entire Admin Server. All the life cycle
98     operations on all server side entities are exposed by this controller. Thus
99     it is the <strong> management interface <strong> for the object that
100     controls the various entities like Server Instances.
101     <p>
102     It is guaranteed that there will always be single instance of this type
103     of MBean in the MBeanServer.
104     <p>
105     ObjectName of this MBean is: ias:type=controller
106 */

107
108 public class ServerController extends AdminBase {
109     private Hashtable JavaDoc mStreamTable = null;
110     private static final Logger JavaDoc sLogger =
111             Logger.getLogger(AdminConstants.kLoggerName);
112     // i18n StringManager
113
private static StringManager localStrings =
114         StringManager.getManager( ServerController.class );
115     private AdminContext mAdminContext;
116
117     public ServerController() {
118         mStreamTable = new Hashtable JavaDoc();
119     }
120
121     public ServerController(AdminContext adminContext) {
122         this();
123         mAdminContext = adminContext;
124     }
125
126     /**
127         Creates a Server Instance using the Admin Server and given instance name.
128         By default the Server Instance will be created on the same machine and
129         any available port and will be auto-restarted when the entire server
130         is restarted after shutdown. The corresponding MBean will be
131         registered in the MBeanServer.
132
133         @param instanceName - name of the Server Instance
134         @param hostPort - an instance of HostAndPort to indicate host:port
135         @param runAsUser - The user id with which the instance and its config
136         will be created. If it is null, the instance will be created with
137         default user id ie the admin userid.
138         @param autoStart - boolean indicating whether this Instance will be
139             started when the entire Server is restarted.
140
141         @throws ControlException if the Server Instance can't be created
142     */

143     
144     public void createServerInstance(String JavaDoc instanceName,
145                                      HostAndPort hostPort,
146                                      String JavaDoc runAsUser,
147                                      boolean autoStart)
148         throws InstanceAlreadyExistsException, ControlException
149     {
150         if(isBadInstanceName(instanceName))
151         {
152             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.bad_instance_name", instanceName );
153             throw new ControlException( msg );
154         }
155         
156         ObjectName JavaDoc siObjectName =
157             ObjectNames.getServerInstanceObjectName(instanceName);
158         MBeanServer JavaDoc mbs = MBeanServerFactory.getMBeanServer();
159         if (!mbs.isRegistered(siObjectName))
160         {
161             try
162             {
163                 InstanceDefinition instance = new InstanceDefinition(instanceName,
164                         hostPort.getPort());
165                 if (runAsUser != null)
166                 {
167                     instance.setUser(runAsUser);
168                 }
169                 ServerManager.instance().createServerInstance(instance);
170                 sLogger.log(Level.INFO, "mbean.created_instance", instanceName);
171             }
172             catch (Exception JavaDoc e)
173             {
174                 sLogger.log(Level.WARNING, "mbean.create_instance_failed", e);
175                 throw new ControlException(e.getMessage());
176             }
177         }
178         else
179         {
180             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.instance_already_exists", instanceName );
181         throw new InstanceAlreadyExistsException( msg );
182         }
183     }
184
185     public void createServerInstance(HostAndPort hAndp,
186                                      String JavaDoc instanceName,
187                                      String JavaDoc mailHost,
188                                      String JavaDoc user,
189                                      String JavaDoc docRoot,
190                                      int jmsPort,
191                                      String JavaDoc jmsUser,
192                                      String JavaDoc jmsPasswd,
193                                      boolean autoStart)
194         throws InstanceAlreadyExistsException, ControlException
195     {
196         if(isBadInstanceName(instanceName))
197         {
198             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.bad_instance_name" );
199             throw new ControlException( msg );
200         }
201         
202         ArgChecker.checkValid(hAndp, "hostport"); //noi18n
203
ArgChecker.checkValid(instanceName, "instanceName",
204                               StringValidator.getInstance()); //noi18n
205
ObjectName JavaDoc siObjectName =
206             ObjectNames.getServerInstanceObjectName(instanceName);
207         MBeanServer JavaDoc mbs = MBeanServerFactory.getMBeanServer();
208         if (!mbs.isRegistered(siObjectName))
209         {
210             try
211             {
212                 /* call the script to create instance */
213                 InstanceDefinition instance =
214                     new InstanceDefinition(hAndp.getHost(), hAndp.getPort(),
215                         instanceName, mailHost, user, docRoot, jmsPort,
216                         jmsUser, jmsPasswd);
217                 ServerManager.instance().createServerInstance(instance);
218                 sLogger.log(Level.INFO, "mbean.created_instance", instanceName);
219             }
220             catch (Exception JavaDoc e)
221             {
222                 sLogger.log(Level.WARNING, "mbean.create_instance_failed", e);
223                 throw new ControlException(e.getMessage());
224             }
225         }
226         else
227         {
228             throw new InstanceAlreadyExistsException(instanceName);
229         }
230     }
231     /**
232         Deletes an existing Server Instance. The instance should not be
233         running. The corresponding MBean will be deregistered from the
234         MBeanServer.
235
236         @param instanceName - the name of the Server Instance
237         @throws ControlException if the Server Instance is running or does not
238         exist or some other problem occurs
239     */

240     
241     public void deleteServerInstance(String JavaDoc instanceName) throws
242         NoSuchInstanceException, ControlException
243     {
244         if (instanceName == null)
245         {
246             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.null_name" );
247             throw new IllegalArgumentException JavaDoc( msg );
248         }
249
250         ServerManager sm = ServerManager.instance();
251         
252         /* get running status */
253         if(!sm.instanceExists(instanceName))
254         {
255             String JavaDoc msg = localStrings.getString(
256                     "admin.server.core.mbean.config.instance_does_not_exist",
257                     instanceName);
258             throw new ControlException(msg);
259         }
260         boolean alive = false;
261         RMIClient serverInstancePinger = AdminChannel.getRMIClient(instanceName);
262         alive = serverInstancePinger.isAlive();
263         if(alive)
264         {
265             String JavaDoc msg = localStrings.getString(
266                     "admin.server.core.mbean.config.delete_alive_instance",
267                     instanceName);
268             throw new ControlException(msg);
269         }
270
271         
272         try
273         {
274             // Unregister all instance related MBeans
275
MBeanServer JavaDoc mbs = MBeanServerFactory.getMBeanServer();
276             ObjectName JavaDoc[] objectNames = ObjectNameHelper.
277                     getInstanceRelatedMBeans(mbs, instanceName);
278             for(int i=0; i<objectNames.length; i++)
279             {
280                 try
281                 {
282                     mbs.unregisterMBean(objectNames[i]);
283                 }
284                 catch(Exception JavaDoc e)
285                 {
286                     sLogger.log(Level.CONFIG, "delete_unregistration_failed",
287                             objectNames[i]);
288                 }
289             }
290             // Message to Config to refresh contexts
291
InstanceEnvironment instanceEnvironment = new
292                     InstanceEnvironment(instanceName);
293             String JavaDoc fileUrl = instanceEnvironment.getConfigFilePath();
294             ConfigFactory.removeConfigContext(fileUrl);
295
296             String JavaDoc instanceRoot = instanceEnvironment.getInstancesRoot();
297             deleteJMSProviderInstance(instanceRoot, instanceName);
298             
299             // Now stop it delete the files from file system */
300
sm.deleteServerInstance(instanceName);
301             sLogger.log(Level.INFO, "mbean.del_instance_ok", instanceName);
302         }
303         catch(Exception JavaDoc e)
304         {
305             sLogger.log(Level.WARNING, "mbean.del_instance_failed", e);
306             throw new ControlException(e.getMessage());
307         }
308     }
309
310     /**
311     Delete JMS provider data specific to this instance.
312     */

313     private void deleteJMSProviderInstance(String JavaDoc instancesRoot,
314                                            String JavaDoc instanceName)
315     {
316         InstanceEnvironment instanceEnvironment;
317         ConfigContext configContext;
318         JmsService jmsService;
319         String JavaDoc fileUrl;
320
321         try
322         {
323             if (mAdminContext != null) {
324                 configContext = mAdminContext.getAdminConfigContext();
325             } else {
326                 instanceEnvironment = new InstanceEnvironment(instanceName);
327                 fileUrl = instanceEnvironment.getConfigFilePath();
328                 configContext = ConfigFactory.createConfigContext(fileUrl);
329             }
330
331             jmsService = (JmsService)ConfigBeansFactory.getConfigBeanByXPath(
332                 configContext, ServerXPathHelper.XPATH_JMS_SERVICE);
333         
334             if ((jmsService != null) && (jmsService.isEnabled())) {
335                 JMSAdmin jmsAdmin = null;
336                 JavaConfig javaConfig;
337                     String JavaDoc java_home = null,
338                     domainName = null,
339                         mqInstanceName = null,
340                         mqBin = null,
341                     argArray[] = new String JavaDoc [ 4 ];
342
343                 javaConfig = (JavaConfig)ConfigBeansFactory.getConfigBeanByXPath(
344                 configContext, ServerXPathHelper.XPATH_JAVACONFIG);
345                 java_home = javaConfig.getJavaHome();
346
347                 mqBin = System.getProperty("com.sun.aas.imqBin");
348                 domainName = ServerManager.instance().getDomainName();
349
350                 jmsAdmin = IASJmsUtil.getJMSAdminFactory().getJMSAdmin();
351
352             /*
353              * Use utility method to construct MQ broker instance name
354              */

355             mqInstanceName = IASJmsUtil.getBrokerInstanceName(domainName,
356                         instanceName, jmsService);
357
358             argArray[0] = "-javahome";
359             argArray[1] = java_home;
360             argArray[2] = "-varhome";
361         String JavaDoc mqInstanceDir = instancesRoot + File.separator +
362                            IASJmsUtil.MQ_DIR_NAME;
363             argArray[3] = mqInstanceDir;
364
365             /*
366              * Call MQ SPI method to delete the instance.
367              */

368                 jmsAdmin.deleteProviderInstance(mqBin, argArray, mqInstanceName);
369             }
370         }
371         catch (Exception JavaDoc e)
372         {
373             sLogger.log(Level.FINE, "mbean.del_jms_instance_failed", e);
374         }
375     }
376
377
378     /**
379         Shuts down the entire Admin Server.
380         It starts a thread in which the server is stopped.
381         This method <code> has to </code> give call to the
382         stop script asynchronously.
383         This method returns immediately after spawning a
384         Shutdown thread. There may be some timing issues
385         with this method.
386     */

387     
388     public void shutdown()
389     {
390         sLogger.log(Level.INFO, "mbean.shutdown_started");
391 // String adminId = ServerManager.ADMINSERVER_ID;
392
String JavaDoc adminId = AdminService.getAdminService().getInstanceName();
393         new Thread JavaDoc(new ShutdownThread(adminId)).start();
394     }
395
396     /**
397         Shuts down all the Server Processes, and exits, so that to restart
398         the system, some external script has to be run by administrator.
399         All the MBeans will be deregistered, all the JVMs will be gracefully
400         stopped.
401     */

402     
403     public void shutdownAndExit()
404     {
405     }
406
407     /**
408         Restarts the entire Server implying a shutdown and then start.
409         Start implies it as in the method start.
410
411         @see #start
412     */

413
414     public void restart() throws ControlException
415     {
416     }
417
418     /**
419         Gets the progress for an (earlier) operation with a specific RequestID.
420     */

421     /*
422     public OperationProgress getProgress(RequestID requestID) throws
423         ControlException
424     {
425         return null;
426     }
427
428     */

429
430     public String JavaDoc getVersion() throws ControlException
431     {
432     return Version.getVersion();
433     }
434
435     public String JavaDoc getFullVersion() throws ControlException
436     {
437           return Version.getFullVersion();
438     }
439
440     /**
441         Uploads the given ByteChunk to the Server. This will be saved
442         in an area defined by the server and then the complete path
443         where the file is saved is returned. This path can later be
444         used for deployment to a specific Server Instance. Argument may not be
445         null.
446      
447         @param byteChunk the ByteChunk instance that contains bytes of a file.
448         @throws IllegalArgumentException, ControlException
449         @return String representing the complete path of the file.
450     */

451     
452     public String JavaDoc uploadToServer(ByteChunk byteChunk) throws ControlException
453     {
454         if (byteChunk == null)
455         {
456             throw new IllegalArgumentException JavaDoc();
457         }
458         String JavaDoc fileName = byteChunk.getChunkedFileName();
459         String JavaDoc localPath = AdminService.getAdminService().getTempDirPath();
460         String JavaDoc targetDirName = byteChunk.getTargetDir();
461         if (targetDirName != null)
462         {
463             File JavaDoc targetDir = new File JavaDoc(localPath, targetDirName);
464             if (!targetDir.exists())
465             {
466                 targetDir.mkdir();
467             }
468             localPath = FileUtils.safeGetCanonicalPath(targetDir);
469         }
470         File JavaDoc uploadFile = new File JavaDoc(localPath, fileName);
471         localPath = FileUtils.safeGetCanonicalPath(uploadFile);
472         if (byteChunk.isFirst())
473         {
474             /* The file in temporary area should not exist on first chunk */
475             if (uploadFile.exists())
476             {
477                 /*
478                 String msg = localStrings.getString
479                     ("admin.server.core.mbean.config.temp_upload_file_exists",
480                      localPath);
481                 throw new ControlException(msg);
482                 */

483                 /* Commenting out the above as a workaround for the Windows problem.
484                    One more try will be done, and it will only be logged as a message for
485                    now. 07/17/2002 - Kedar (this is a workaround) */

486                 sLogger.log(Level.INFO, "mbean.temp_upload_file_exists", localPath);
487                 boolean couldDelete = uploadFile.delete();
488                 if (couldDelete)
489                 {
490                     sLogger.log(Level.FINE, "mbean.delete_temp_file_ok", localPath);
491                 }
492                 else
493                 {
494                     sLogger.log(Level.INFO, "mbean.delete_temp_file_failed", localPath);
495                 }
496             }
497             OutputStream JavaDoc outStream = createOutputStream(localPath);
498             mStreamTable.put(localPath, outStream);
499             sLogger.log(Level.INFO, "mbean.begin_upload", localPath);
500         }
501         saveFile(localPath, byteChunk);
502         return ( localPath );
503     }
504     
505     private void saveFile(String JavaDoc filePath, ByteChunk aChunk)
506         throws ControlException
507     {
508         OutputStream JavaDoc sOut = null;
509         try
510         {
511             sOut = (OutputStream JavaDoc) mStreamTable.get(filePath);
512             byte[] bytes = aChunk.getBytes();
513             sOut.write(bytes);
514         }
515         catch(Exception JavaDoc e)
516         {
517             throw new ControlException(e.getMessage());
518         }
519         finally
520         {
521             try
522             {
523                 if (aChunk.isLast())
524                 {
525                     sOut.close();
526                     mStreamTable.remove(filePath);
527                     sLogger.log(Level.INFO, "mbean.upload_done", filePath);
528                 }
529             }
530             catch(Exception JavaDoc fe)
531             {
532                 throw new ControlException(fe.getMessage());
533             }
534         }
535     }
536     
537     private OutputStream JavaDoc createOutputStream(String JavaDoc filePath) throws ControlException
538     {
539         OutputStream JavaDoc fOut = null;
540         
541         try
542         {
543             fOut = new FileOutputStream JavaDoc(filePath);
544         }
545         catch(Exception JavaDoc e)
546         {
547             try
548             {
549                 if (fOut != null)
550                 {
551                     fOut.close();
552                 }
553             }
554             catch (Exception JavaDoc ce)
555             {
556                 sLogger.log(Level.WARNING, "mbean.upload_failed", filePath);
557             }
558             
559             throw new ControlException(e.getMessage());
560         }
561         return ( fOut );
562     }
563
564     public String JavaDoc[] listServerInstances()
565     {
566             ServerManager sm = ServerManager.instance();
567             boolean countAdmin = false;
568             String JavaDoc[] instanceNames =
569                     sm.getInstanceNames (countAdmin); //do not count admin itself.
570
return ( instanceNames );
571     }
572         
573   //***************************************************
574
//static MBean attributes and opeartions descriptions
575
/** Implementation of <code>getMBeanInfo()</code>
576      * Uses helper class <code>MBeanEasyConfig</code> to construct whole MBeanXXXInfo tree.
577      * @return <code>MBeanInfo</code> objects containing full MBean description.
578      */

579   static String JavaDoc[] mAttrs = new String JavaDoc[0];
580   static String JavaDoc[] mOpers = {
581       "createServerInstance(String instanceName, com.sun.enterprise.admin.util.HostAndPort hostPort, String runAsUser, boolean autoStart), ACTION",
582       "deleteServerInstance(String instanceName), ACTION",
583       "shutdown(), ACTION",
584       "shutdownAndExit(), ACTION",
585       "restart(), ACTION",
586 // "getProgress(com.sun.enterprise.admin.common.RequestID requestID), ACTION",
587
"getVersion(), ACTION_INFO",
588       "getFullVersion(), ACTION_INFO",
589       "uploadToServer(com.sun.enterprise.admin.common.ByteChunk byteChunk), ACTION_INFO",
590       "listServerInstances(), INFO",
591       "prepareDownload(String filePath), ACTION",
592       "downloadFile(int chunkIndex), ACTION",
593       "stopDomain(boolean stopAdmin), ACTION",
594       "getRunningInstanceNames(), ACTION",
595       "listDomains(), INFO",
596   };
597     
598     /** Implementation of <code>getMBeanInfo()</code>
599         Uses helper class <code>MBeanEasyConfig</code> to construct whole MBeanXXXInfo tree.
600         @return <code>MBeanInfo</code> objects containing full MBean description.
601     */

602     public MBeanInfo JavaDoc getMBeanInfo()
603     {
604         try
605         {
606             return (new MBeanEasyConfig(getClass(), mAttrs, mOpers, null)).getMBeanInfo();
607         }
608         catch(Exception JavaDoc e)
609         {
610             sLogger.log(Level.WARNING, "mbean.mbeaninfo_failed", e);
611             return null;
612         }
613     }
614
615     private final class Lock
616     {
617         private boolean inUse;
618
619         private Lock()
620         {
621             inUse = false;
622         }
623
624         private synchronized void acquire()
625             throws InterruptedException JavaDoc, IllegalAccessException JavaDoc
626         {
627             while (inUse)
628             {
629                 wait();
630             }
631             inUse = true;
632         }
633
634         private synchronized void release() throws IllegalAccessException JavaDoc
635         {
636             inUse = false;
637             notify();
638         }
639
640         private synchronized void attempt(long milliseconds)
641             throws InterruptedException JavaDoc, IllegalAccessException JavaDoc
642         {
643             if (inUse)
644             {
645                 wait(milliseconds);
646                 if (inUse) //The lock is still in use. Give up.
647
{
648                     String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.another_thread_holding_lock" );
649                     throw new IllegalAccessException JavaDoc( msg );
650                 }
651             }
652             inUse = true;
653         }
654     }
655
656     private static final class DownloadInfo
657     {
658         private File JavaDoc downloadFile;
659         private int numChunks;
660         private long numBytesRead;
661         private boolean isPrepared;
662
663         private DownloadInfo()
664         {
665             reset();
666         }
667
668         private synchronized void reset()
669         {
670             downloadFile = null;
671             numChunks = 0;
672             numBytesRead = 0;
673             isPrepared = false;
674         }
675     }
676
677     private Lock lock;
678     private DownloadInfo downloadInfo;
679
680
681     /**
682      */

683     public Object JavaDoc prepareDownload(String JavaDoc filePath) throws ControlException
684     {
685         sLogger.log(Level.CONFIG, "mbean.prep_download", filePath);
686         filePath = RelativePathResolver.resolvePath(filePath);
687         File JavaDoc downloadFile = new File JavaDoc(filePath);
688         if (!downloadFile.exists())
689         {
690             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.file_doesnot_exist", filePath );
691             throw new ControlException( msg );
692         }
693         try
694         {
695             if (lock == null)
696             {
697                 lock = new Lock();
698             }
699             lock.attempt(1000);
700         }
701         catch (Exception JavaDoc ie)
702         {
703             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.could_not_acquire_lock", ie.toString() );
704             throw new ControlException( msg );
705         }
706         if (downloadInfo == null)
707         {
708             downloadInfo = new DownloadInfo();
709         }
710         downloadInfo.downloadFile = downloadFile;
711         long size = downloadInfo.downloadFile.length();
712         downloadInfo.numChunks = Math.round(size/ByteChunk.kChunkMaxSize);
713         if (downloadInfo.numChunks * ByteChunk.kChunkMaxSize < size)
714         {
715             downloadInfo.numChunks += 1;
716         }
717         /*
718           Debug.println("File=" + downloadInfo.downloadFile.getAbsolutePath() +
719                       ", " + "size=" + size + ", " +
720                       "Num chunks=" + downloadInfo.numChunks);
721         */

722         downloadInfo.isPrepared = true;
723         return null;
724     }
725
726     /**
727      */

728     public ByteChunk downloadFile(int chunkIndex) throws ControlException
729     {
730         sLogger.log(Level.FINE, "mbean.begin_download");
731         if (downloadInfo == null)
732         {
733             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.call_preparedownload_first" );
734             throw new ControlException( msg );
735         }
736         else if (!downloadInfo.isPrepared)
737         {
738             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.call_preparedownload_first" );
739             throw new ControlException( msg );
740         }
741         if ((chunkIndex >= downloadInfo.numChunks) || (chunkIndex < 0))
742         {
743             String JavaDoc msg = localStrings.getString( "admin.server.core.mbean.config.invalid_chunk_index" );
744             throw new ControlException( msg );
745         }
746         RandomAccessFile JavaDoc raf = null;
747         ByteChunk byteChunk = null;
748         try
749         {
750             raf = new RandomAccessFile JavaDoc(downloadInfo.downloadFile, "r");
751             byte[] bytes = new byte[ByteChunk.kChunkMaxSize];
752             raf.seek(downloadInfo.numBytesRead);
753             int actualBytesRead = raf.read(bytes, 0, ByteChunk.kChunkMaxSize);
754             /*
755             Debug.println("Read " + actualBytesRead + " from " +
756                           downloadInfo.numBytesRead);
757             */

758             if (actualBytesRead < bytes.length)
759             {
760                 byte[] newBytes = new byte[actualBytesRead];
761                 for (int i = 0; i < newBytes.length; i++)
762                 {
763                     newBytes[i] = bytes[i];
764                 }
765                 bytes = newBytes;
766             }
767             downloadInfo.numBytesRead += actualBytesRead;
768             boolean isFirstChunk = (chunkIndex == 0);
769             boolean isLastChunk =
770                 (chunkIndex == (downloadInfo.numChunks - 1));
771             sLogger.log(Level.FINEST, "chunkIndex = " + chunkIndex +
772                           " isFirstChunk = " + isFirstChunk +
773                           " isLastChunk = " + isLastChunk);
774             byteChunk = new ByteChunk(bytes,
775                              downloadInfo.downloadFile.getAbsolutePath(),
776                              isFirstChunk, isLastChunk);
777         }
778         catch (Exception JavaDoc ioe)
779         {
780             sLogger.log(Level.FINE, "mbean.download_failed", ioe);
781             downloadInfo.reset();
782             try
783             {
784                 lock.release();
785             }
786             catch (Exception JavaDoc e)
787             {
788                 sLogger.log(Level.FINEST, "lock could not be released");
789             }
790             throw new ControlException(ioe.toString());
791         }
792         finally
793         {
794             if (raf != null)
795             {
796                 try { raf.close(); }
797                 catch (IOException JavaDoc ioe) {}
798             }
799             if ((byteChunk != null) && (byteChunk.isLast()))
800             {
801                 try
802                 {
803                     downloadInfo.reset();
804                     lock.release();
805                 }
806                 catch (Exception JavaDoc e)
807                 {
808                     sLogger.log(Level.FINEST, "lock could not be released");
809                 }
810             }
811         }
812         return byteChunk;
813     }
814     
815     /**
816      * validate instance name
817      */

818     private boolean isBadInstanceName(String JavaDoc instanceName)
819     {
820 /* try {
821         StaticTest.checkXMLName(instanceName);
822     } catch(Exception e) {
823         //log the message.
824             sLogger.log(Level.FINE, "Error: The instance name is not a valid xml string");
825         sLogger.log(Level.FINE, e.getMessage(), e);
826         return true;
827     }
828     try {
829         StaticTest.checkObjectName(instanceName);
830     } catch(Exception e) {
831         //log the message.
832             sLogger.log(Level.FINE, "Error: The instance name is not a valid mbean object name");
833         sLogger.log(Level.FINE, e.getMessage(), e);
834         return true;
835     }
836         return false;
837  **/

838         /*
839             RAMAKANTH: Uncomment the above code. Returning false for timebeing
840             to get startInstance working. RI Milestone 1. 03/20/2003.
841          */

842         return false;
843     }
844     
845     /**
846         Stops the domain for which this is the ServerController.
847         Depending on the parameter passed, the admin-server will
848         itself be shutdown. All the instances will be stopped concurrently.
849         Note that this is a best attempt.
850         @throws ControlException in case there any error before starting the
851         stop operation. Once the instances start stopping, if there any
852         exceptions, they will be ignored. Thus this is a "fire and forget"
853         kind of command, becase not much can be done to restore in case
854         of any failure.
855     */

856     public void stopDomain(boolean stopAdmin) throws ControlException
857     {
858         String JavaDoc domainName = ServerManager.instance().getDomainName();
859         if(stopAdmin)
860         {
861             sLogger.log(Level.INFO, "domain.stop_domain_admin", domainName);
862         }
863         else
864         {
865             sLogger.log(Level.INFO, "domain.stop_domain_noadmin", domainName);
866         }
867         // First stop all instances sequentially
868
stopAllInstances(false);
869         // Then if asked for, shutdown the admin server
870
if(stopAdmin)
871         {
872             this.shutdown();
873         }
874     }
875     
876     /**
877         Returns the array of DomainEntry elements. This does not
878         require a Collection or Iterator, for these data structures
879         are not Serializable at least because of the internal implementation.
880         The DomainRegistry.iterator() returns an Inner Class instance,
881         which implemets an Iterator and the same iterator can't be
882         passed on, as it is not Serializable.
883         @return an array of DomainEntry elements, an empty array if
884         there are no domains.
885         @throws ControlException in case the DomainRegistry fails
886     */

887     public DomainEntry[] listDomains() throws ControlException
888     {
889         DomainEntry[] domains = null;
890         try
891         {
892             DomainRegistry domainRegistry = DomainRegistry.newInstance();
893             int size = domainRegistry.size();
894             domains = new DomainEntry[size];
895             Iterator JavaDoc innerIter = domainRegistry.iterator();
896             int i = 0;
897             while (innerIter.hasNext())
898             {
899                 domains[i++] = (DomainEntry)innerIter.next();
900             }
901             assert size == i;
902         }
903         catch (Exception JavaDoc e)
904         {
905             throw new ControlException(e.getMessage());
906         }
907         return ( domains );
908     }
909     
910     /**
911         This particular method is called when the stopDomain() is called
912         from the UI. Note that it does not call the ManagedServerInstance
913         MBean for stopping a particular instance. This is done for the fact
914         that the ManagedServerInstanceMBean never caches the state of a
915         running instance. Note that depending upon the parameter passed,
916         the instances will be stopped concurrently. A best effort will
917         be made to stop the instances.
918         @param boolean indicating the method (concurrent/serial) to stop instances.
919     */

920
921     private void stopAllInstances(boolean atOnce)
922     {
923         String JavaDoc[] instanceIds = getRunningInstanceNames();
924         
925         if(!atOnce) /*only sequentially */
926         {
927             for (int i = 0; i < instanceIds.length; i++)
928             {
929                 sLogger.log(Level.INFO, "mbean.stop_instance", instanceIds[i]);
930                 stopInstance(instanceIds[i]);
931             }
932         }
933         else /*concurrently, not implemented as yet 07/21/2002 */
934         {
935             throw new UnsupportedOperationException JavaDoc("not impl yet");
936         }
937     }
938     
939     /**
940         Returns an array of running instances names. Internally the mbean
941         representing that mbean is invoked to determine the status.
942     */

943     public String JavaDoc[] getRunningInstanceNames()
944     {
945         String JavaDoc[] allInstances = ServerManager.instance().
946                 getInstanceNames(false);
947         Vector JavaDoc runningInstances = new Vector JavaDoc();
948         String JavaDoc[] runners = null;
949         int num = 0;
950         
951         for(int i = 0; i < allInstances.length ; i++)
952         {
953             if (isInstanceAlive(allInstances[i]))
954             {
955                 runningInstances.add(allInstances[i]);
956                 num++;
957                 sLogger.log(Level.FINE, "mbean.instance_up", allInstances[i]);
958             }
959             else
960             {
961                 sLogger.log(Level.FINE, "mbean.instance_down", allInstances[i]);
962             }
963         }
964         if (num > 0)
965         {
966             runners = new String JavaDoc[num];
967             runners = (String JavaDoc[]) runningInstances.toArray(runners);
968         }
969         else
970         {
971             runners = new String JavaDoc[0];
972         }
973         
974         return ( runners );
975     }
976     
977     private void stopInstance(String JavaDoc instanceId)
978     {
979         ObjectName JavaDoc objName =
980             ObjectNames.getServerInstanceObjectName(instanceId);
981         final String JavaDoc kStopMethodName = "stop";
982         final Object JavaDoc[] params = new Integer JavaDoc[]{new Integer JavaDoc(600)};
983         final String JavaDoc[] sign = new String JavaDoc[]{"int"};
984         try
985         {
986             invokeMBean(objName, kStopMethodName, params, sign);
987         }
988         catch(Exception JavaDoc e)
989         {
990             sLogger.log(Level.CONFIG, "failure in invoking MBean", e);
991         }
992     }
993     
994     private boolean isInstanceAlive(String JavaDoc instanceId)
995     {
996         ObjectName JavaDoc objName =
997             ObjectNames.getServerInstanceObjectName(instanceId);
998         final String JavaDoc kStatusMethodName = "getStatus";
999         try
1000        {
1001        /* method that takes in no params */
1002            final ServerInstanceStatus status = (ServerInstanceStatus)
1003                invokeMBean(objName, kStatusMethodName, null, null);
1004            return ( status.isRunning() );
1005        }
1006        catch (Exception JavaDoc e)
1007        {
1008            sLogger.log(Level.CONFIG, "failure in invoking MBean", e);
1009            return false;
1010        }
1011    }
1012    
1013    private Object JavaDoc invokeMBean(ObjectName JavaDoc objName, String JavaDoc operationName,
1014            Object JavaDoc[] params, String JavaDoc[] signature) throws Exception JavaDoc
1015    {
1016        MBeanServer JavaDoc mbs = MBeanServerFactory.getMBeanServer();
1017        return ( mbs.invoke(objName, operationName, params, signature) );
1018    }
1019    
1020    /**
1021        Returns the License information about the installed appserver.
1022        @return String which contains the license information.
1023    */

1024
1025    public String JavaDoc getLicenseInfo()
1026    {
1027            String JavaDoc licenseInfo = localStrings.getString(
1028                    "admin.server.core.mbean.license_info");
1029            return licenseInfo;
1030    }
1031        
1032    /** Every resource MBean should override this method to execute specific
1033     * operations on the MBean. This method is enhanced in 8.0. It was a no-op
1034     * in 7.0. In 8.0, it is modified to invoke the actual method through
1035     * reflection.
1036     * @since 8.0
1037     * @see javax.management.MBeanServer#invoke
1038     * @see #getImplementingClass
1039     */

1040    protected Class JavaDoc getImplementingClass() {
1041        return ( this.getClass() );
1042    }
1043    
1044    /** Reflection requires the implementing object. */
1045    protected Object JavaDoc getImplementingMBean() {
1046        return ( this );
1047    }
1048    
1049}
1050
1051/**
1052    A class to stop this very process by giving triggering the
1053    signal externally. The signal is triggered by calling stop
1054    on the admin server. In short a process A forks a child
1055    process B, which in turn shuts process A down. The forked
1056    process becomes zombie?
1057*/

1058
1059class ShutdownThread implements Runnable JavaDoc
1060{
1061    private String JavaDoc mInstanceId;
1062    /*package*/ ShutdownThread(String JavaDoc instanceId)
1063    {
1064        mInstanceId = instanceId;
1065    }
1066    
1067    public void run()
1068    {
1069    ServerManager svrMgr = ServerManager.instance();
1070    int testPort = 9000;
1071    /* testPort is actually not used for stopping the instance,
1072        it's use is limited to construct the InstanceDefinition
1073        class
1074    */

1075    try
1076    {
1077        InstanceDefinition instanceDef = new InstanceDefinition(mInstanceId,
1078            testPort);
1079        svrMgr.stopServerInstance (instanceDef);
1080    }
1081    catch (Exception JavaDoc e)
1082    {
1083        //This Exception can be ignored.
1084
}
1085    }
1086}
1087
Popular Tags