KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ha > framework > server > FarmMemberService


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ha.framework.server;
23
24 import java.io.File JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.*;
28
29 import org.jboss.deployment.Deployer;
30 import org.jboss.deployment.scanner.URLDeploymentScanner;
31 import org.jboss.ha.framework.interfaces.HAPartition;
32 import org.jboss.system.server.ServerConfig;
33 import org.jboss.system.server.ServerConfigLocator;
34 import org.jboss.system.server.ServerConfigUtil;
35 import org.jboss.ha.framework.server.ClusterFileTransfer.ClusterFileTransferException;
36
37 /**
38  *
39  * @author <a HREF="mailto:andreas@jboss.org">Andreas Schaefer</a>
40  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
41  * @version $Revision: 58576 $
42  *
43  * <p><b>20021014 andreas schaefer:</b>
44  * <ul>
45  * <li>Initial import
46  * </ul>
47  * <p><b>20020809 bill burke:</b>
48  * <ul>
49  * <li>Rewrote as a Scanner instead. Also on boot-up asks cluster for deployable files
50  * </ul>
51  */

52 public class FarmMemberService extends URLDeploymentScanner implements FarmMemberServiceMBean
53 {
54    protected ClusterPartitionMBean mClusterPartition = null;
55    protected String JavaDoc mBackgroundPartition = ServerConfigUtil.getDefaultPartitionName();
56    protected HAPartition mHAPartition;
57    private File JavaDoc mTempDirectory;
58    private ClusterFileTransfer mFileTransfer;
59
60    protected final static String JavaDoc SERVICE_NAME = "FarmMemberService";
61    protected HashMap parentDUMap = new HashMap();
62    
63    protected ArrayList remotelyDeployed = new ArrayList ();
64    protected ArrayList remotelyUndeployed = new ArrayList ();
65
66    public String JavaDoc getPartitionName()
67    {
68       return mBackgroundPartition;
69    }
70    
71    public void setPartitionName( String JavaDoc pPartitionName )
72    {
73       log.warn("setPartitionName does nothing; use setClusterPartition");
74    }
75
76    public ClusterPartitionMBean getClusterPartition()
77    {
78       return mClusterPartition;
79    }
80
81    public void setClusterPartition(ClusterPartitionMBean clusterPartition)
82    {
83       if( ( getState () != STARTED ) && ( getState () != STARTING ) )
84       {
85          this.mClusterPartition = clusterPartition;
86       }
87    }
88
89    /** Backward compatibility, mapped to the URLs attribute of URLDeploymentScannerMBean
90     * @deprecated
91     */

92    public void setFarmDeployDirectory(String JavaDoc urls)
93       throws MalformedURLException JavaDoc
94    {
95       super.setURLs(urls);
96    }
97
98    /** Backward compatibility, but ignored as it does nothing.
99     * @deprecated
100     */

101    public void setScannerName(String JavaDoc name)
102    {
103       log.warn("ScannerName does nothing");
104    }
105
106    // Service implementation ----------------------------------------
107

108    public String JavaDoc getName()
109    {
110       return "Farm Member Service";
111    }
112    
113    /**
114     * Looks up the Server Config instance to figure out the
115     * temp-directory and the farm-deploy-directory
116     **/

117    protected void createService() throws Exception JavaDoc
118    {
119       super.createService();
120       ServerConfig lConfig = ServerConfigLocator.locate();
121       mTempDirectory = lConfig.getServerTempDir();
122       
123       createUnexistingLocalDir ();
124    }
125    /**
126     * Register itself as RPC-Handler to the HA-Partition
127     * and add the farm deployment directory to the scanner
128     **/

129    protected void startService()
130       throws Exception JavaDoc
131    {
132       try
133       {
134          log.debug( "registerRPCHandler" );
135          
136          if (mClusterPartition == null)
137          {
138             throw new IllegalStateException JavaDoc("Must set the ClusterPartition property before calling start");
139          }
140          
141          mHAPartition = mClusterPartition.getHAPartition();
142          mBackgroundPartition = mHAPartition.getPartitionName();
143          
144          mHAPartition.registerRPCHandler( SERVICE_NAME, this );
145
146          mFileTransfer = new ClusterFileTransfer(mHAPartition, buildParentFolderMapping());
147
148          ArrayList response = mHAPartition.callMethodOnCoordinatorNode(
149             SERVICE_NAME,
150             "farmDeployments",
151             new Object JavaDoc[] {}, new Class JavaDoc[] {},
152             true
153          );
154
155          log.debug("Found "+response.size()+" farmDeployments responses");
156          for (int i = 0; i < response.size(); i++)
157          {
158             Object JavaDoc map = response.get(i);
159             if ( map != null && map instanceof HashMap )
160             {
161                HashMap farmed = (HashMap) map;
162                pullNewDeployments(mHAPartition, farmed);
163             }
164          }
165
166          // scan before we enable the thread, so JBoss version shows up afterwards
167
scannerThread.doScan();
168
169          // enable scanner thread if we are enabled
170
scannerThread.setEnabled(isScanEnabled());
171       }
172       catch(Exception JavaDoc e)
173       {
174          this.logException(e);
175          throw e;
176       }
177    }
178    
179
180    protected void pullNewDeployments(HAPartition partition, HashMap farmed)
181    {
182       log.info("**** pullNewDeployments ****");
183       Iterator it = farmed.keySet().iterator();
184       while (it.hasNext())
185       {
186          String JavaDoc depName = (String JavaDoc)it.next();
187          DeployedURL du = (DeployedURL)parentDUMap.get(depName);
188          Date last = (Date)farmed.get(depName);
189          if (du != null)
190          {
191             Date theLast = new Date(du.getFile().lastModified());
192             if (!theLast.before(last))
193             {
194                continue;
195             }
196          }
197
198          String JavaDoc parentName = depName.substring(0, depName.indexOf('/'));
199          File JavaDoc destFile = new File JavaDoc(depName);
200          try
201          {
202             mFileTransfer.pull(destFile,parentName);
203             synchronized (remotelyDeployed)
204             {
205                remotelyDeployed.add (destFile.getName());
206             }
207          }
208          catch(ClusterFileTransferException e)
209          {
210             // log the exception and continue with the next deployment
211
this.logException(e);
212          }
213       }
214    }
215
216    // return mapping of Farming folder names to the File
217
private Map buildParentFolderMapping()
218    {
219       Map map = new HashMap();
220       URL JavaDoc[] urls = (URL JavaDoc[]) urlList.toArray( new URL JavaDoc[] {} );
221       for (int i = 0; i < urlList.size(); i++)
222       {
223          if (urls[i].getProtocol().equals("file"))
224          {
225             File JavaDoc file = new File JavaDoc(urls[i].getFile());
226             if (file.isDirectory())
227             {
228                map.put(file.getName(),file);
229             }
230
231          }
232       }
233       return map;
234    }
235
236    protected File JavaDoc findParent(String JavaDoc parentName)
237    {
238       URL JavaDoc[] urls = (URL JavaDoc[]) urlList.toArray( new URL JavaDoc[] {} );
239       for (int i = 0; i < urlList.size(); i++)
240       {
241          if (urls[i].getProtocol().equals("file"))
242          {
243             File JavaDoc file = new File JavaDoc(urls[i].getFile());
244             if (file.isDirectory())
245             {
246                if (file.getName().equals(parentName)) return file;
247             }
248          }
249       }
250       return null;
251    }
252
253    public HashMap farmDeployments()
254    {
255       log.debug("farmDeployments request, parentDUMap.size="+parentDUMap.size());
256       Iterator it = parentDUMap.keySet().iterator();
257       HashMap farmed = new HashMap();
258       while(it.hasNext())
259       {
260          String JavaDoc key = (String JavaDoc)it.next();
261          DeployedURL du = (DeployedURL)parentDUMap.get(key);
262          farmed.put(key, new Date(du.getFile().lastModified()));
263       }
264       return farmed;
265    }
266    
267    public void farmDeploy( String JavaDoc parentName, File JavaDoc destFile, Date date )
268    {
269       try
270       {
271          File JavaDoc parent = findParent(parentName);
272          if (parent == null)
273          {
274             log.info("Could not find parent: " + parentName + " for deployment: " + destFile + ", data: " + date);
275             return;
276          }
277          
278          String JavaDoc fullName = parentName + "/" + destFile.getName();
279
280          DeployedURL du = null;
281          synchronized(parentDUMap)
282          {
283             du = (DeployedURL)parentDUMap.get(fullName);
284          }
285          boolean deployIt = false;
286          if (du == null)
287          {
288             deployIt = true;
289          }
290          else
291          {
292             Date lastChanged = new Date(du.getFile().lastModified());
293             deployIt = lastChanged.before(date);
294          }
295
296          if (deployIt)
297          {
298             // we remember this deployment to avoid recursive farm calls!
299
//
300
synchronized (remotelyDeployed)
301             {
302                remotelyDeployed.add (fullName);
303             }
304
305             log.info( "farmDeployment(), deploy locally: " + fullName );
306             // Adjust the date and move the file to /farm
307
// but delete it first if already there
308
File JavaDoc tempFile = new File JavaDoc(this.mTempDirectory, destFile.getName() );
309             File JavaDoc lFarmFile = new File JavaDoc(parent,destFile.getName());
310             if( lFarmFile.exists() ) {
311                if(!lFarmFile.delete()) {
312                   log.info("could not delete target file for farm deployment "+ lFarmFile.getName());
313                }
314             }
315             tempFile.setLastModified( date.getTime() );
316
317             if(! ClusterFileTransfer.localMove(tempFile,lFarmFile ))
318             {
319                log.info("Could not move "+tempFile+" to " + lFarmFile);
320             }
321          }
322          else
323          {
324             log.info(fullName + " is already deployed by farm service on this node");
325          }
326       }
327       catch( Exception JavaDoc e ) {
328          logException( e );
329       }
330    }
331    
332    public void farmUndeploy(String JavaDoc parentName, String JavaDoc fileName)
333    {
334       try {
335          // First check if file is already deployed
336
log.info( "doUndeployment(), File: " + parentName + "/" + fileName);
337          File JavaDoc parent = findParent(parentName);
338          if (parent == null)
339          {
340             log.info("Could not find parent: " + parentName + " for undeployment: " + fileName);
341             return;
342          }
343          File JavaDoc deployed = new File JavaDoc(parent, fileName);
344          if (deployed.exists())
345          {
346             // we remember this undeployment to avoid recursive farm calls!
347
//
348
synchronized (remotelyUndeployed)
349             {
350                String JavaDoc fullName = parentName + "/" + fileName;
351                remotelyUndeployed.add (fullName);
352             }
353
354             if(deployed.delete())
355                log.info( "farmUndeployment(), removed file " + deployed );
356             else
357                log.info( "farmUndeployment(), could not remove file " + deployed );
358          }
359       }
360       catch( Exception JavaDoc e ) {
361          logException( e );
362       }
363    }
364    
365    protected void deploy(final DeployedURL du)
366    {
367       super.deploy(du);
368       File JavaDoc file = du.getFile();
369       File JavaDoc parent = file.getParentFile();
370       if (parent == null) return;
371       
372       String JavaDoc fullName = parent.getName() + "/" + file.getName();
373       synchronized (parentDUMap)
374       {
375          parentDUMap.put(fullName, du);
376       }
377
378       try
379       {
380          // We check if we must do a remote call or not: maybe the deploy
381
// is already the consequence of a farm call! (avoid recusivity!)
382
//
383
boolean consequenceOfRemoteCall = false;
384          synchronized (remotelyDeployed)
385          {
386             consequenceOfRemoteCall = remotelyDeployed.remove (fullName);
387          }
388          
389          if (getState() == STARTING) return;
390
391          if (!consequenceOfRemoteCall)
392          {
393             Date fileDate = new Date(file.lastModified());
394             
395             this.mFileTransfer.push(file, parent.getName(), true);
396
397             mHAPartition.callMethodOnCluster(
398                SERVICE_NAME,
399                "farmDeploy",
400                new Object JavaDoc[] {parent.getName(), file, fileDate},
401                new Class JavaDoc[] {String JavaDoc.class, File JavaDoc.class, Date.class},
402                true
403                );
404          }
405       }
406       catch (ClusterFileTransferException e)
407       {
408          logException(e);
409       }
410       catch (Exception JavaDoc ex)
411       {
412          logException(ex);
413       }
414
415    }
416
417    protected void undeploy(final DeployedURL du)
418    {
419       
420       File JavaDoc file = du.getFile();
421       File JavaDoc parent = file.getParentFile();
422       String JavaDoc parentName = parent.getName();
423       String JavaDoc fileName = file.getName();
424       super.undeploy(du);
425       
426       String JavaDoc fullName = parent.getName() + "/" + file.getName();
427       synchronized (parentDUMap)
428       {
429          parentDUMap.remove(fullName);
430       }
431       
432       if (getState() == STOPPING) return;
433
434       try
435       {
436          // We check if we must do a remote call or not: maybe the undeploy
437
// is already the consequence of a farm call! (avoid recusivity!)
438
//
439
boolean consequenceOfRemoteCall = false;
440          synchronized (remotelyUndeployed)
441          {
442             consequenceOfRemoteCall = remotelyUndeployed.remove (fullName);
443          }
444          
445          if (!consequenceOfRemoteCall)
446          {
447             mHAPartition.callMethodOnCluster(
448                SERVICE_NAME,
449                "farmUndeploy",
450                new Object JavaDoc[] {parentName, fileName},
451                new Class JavaDoc[] {String JavaDoc.class, String JavaDoc.class},
452                true
453                );
454          }
455       }
456       catch (Exception JavaDoc ex)
457       {
458          logException(ex);
459       }
460    }
461
462    /**
463     * Go through the myriad of nested JMX exception to pull out the true
464     * exception if possible and log it.
465     *
466     * @param e The exception to be logged.
467     */

468    private void logException( Throwable JavaDoc e )
469    {
470       if (e instanceof javax.management.RuntimeErrorException JavaDoc)
471       {
472          e = ((javax.management.RuntimeErrorException JavaDoc)e).getTargetError();
473       }
474       else if (e instanceof javax.management.RuntimeMBeanException JavaDoc)
475       {
476          e = ((javax.management.RuntimeMBeanException JavaDoc)e).getTargetException();
477       }
478       else if (e instanceof javax.management.RuntimeOperationsException JavaDoc)
479       {
480          e = ((javax.management.RuntimeOperationsException JavaDoc)e).getTargetException();
481       }
482       else if (e instanceof javax.management.MBeanException JavaDoc)
483       {
484          e = ((javax.management.MBeanException JavaDoc)e).getTargetException();
485       }
486       else if (e instanceof javax.management.ReflectionException JavaDoc)
487       {
488          e = ((javax.management.ReflectionException JavaDoc)e).getTargetException();
489       }
490
491       log.error(e);
492    }
493    
494    protected void createUnexistingLocalDir()
495    {
496       if (this.urlList != null)
497       {
498          Iterator iter = this.urlList.iterator ();
499          while (iter.hasNext ())
500          {
501             URL JavaDoc url = null;
502             try
503             {
504                url = (URL JavaDoc)iter.next ();
505                if (url.getProtocol().equals("file"))
506                {
507                   File JavaDoc targetDir = new File JavaDoc (url.getFile ());
508                   if (!targetDir.exists ())
509                      targetDir.mkdirs ();
510                }
511             }
512             catch (Exception JavaDoc e)
513             {
514                log.info ("Problem while creating a farm directory: " + url, e);
515             }
516          }
517       }
518    }
519 }
520
Popular Tags