FileDocCategorySizeDatePackage
FarmMemberService.javaAPI DocJBoss 4.2.117615Fri Jul 13 20:52:38 BST 2007org.jboss.ha.framework.server

FarmMemberService

public class FarmMemberService extends org.jboss.deployment.scanner.URLDeploymentScanner implements FarmMemberServiceMBean
author
Andreas Schaefer
author
Bill Burke
version
$Revision: 57254 $

20021014 andreas schaefer:

  • Initial import

20020809 bill burke:

  • Rewrote as a Scanner instead. Also on boot-up asks cluster for deployable files

Fields Summary
private MBeanServer
mServer
protected ObjectName
mDeployerName
protected ObjectName
mClusterPartitionName
protected ClusterPartitionMBean
mClusterPartition
protected String
mBackgroundPartition
private File
mTempDirectory
private ClusterFileTransfer
mFileTransfer
protected static final String
SERVICE_NAME
protected HashMap
parentDUMap
protected ArrayList
remotelyDeployed
protected ArrayList
remotelyUndeployed
Constructors Summary
Methods Summary
private java.util.MapbuildParentFolderMapping()

      Map map = new HashMap();
      URL[] urls = (URL[]) urlList.toArray( new URL[] {} );
      for (int i = 0; i < urlList.size(); i++)
      {
         if (urls[i].getProtocol().equals("file"))
         {
            File file = new File(urls[i].getFile());
            if (file.isDirectory())
            {
               map.put(file.getName(),file);
            }

         }
      }
      return map;
   
protected voidcreateService()
Looks up the Server Config instance to figure out the temp-directory and the farm-deploy-directory

      // AbstractDeploymentScanner drops ref to the deployer in destroyService(),
      // so if this is a "re-create" following a destroy, reestablish it
      if (deployer == null && mDeployerName != null)
         setDeployer(mDeployerName); // causes JMX lookup of deployer
      
      super.createService();
      
      ServerConfig lConfig = ServerConfigLocator.locate();
      mTempDirectory = lConfig.getServerTempDir();
      
      createUnexistingLocalDir ();
   
protected voidcreateUnexistingLocalDir()

      if (this.urlList != null)
      {
         Iterator iter = this.urlList.iterator ();
         while (iter.hasNext ())
         {
            URL url = null;
            try
            {
               url = (URL)iter.next ();
               if (url.getProtocol().equals("file"))
               {
                  File targetDir = new File (url.getFile ());
                  if (!targetDir.exists ())
                     targetDir.mkdirs ();
               }
            }
            catch (Exception e)
            {
               log.info ("Problem while creating a farm directory: " + url, e);
            }
         }
      }
   
protected voiddeploy(DeployedURL du)

      super.deploy(du);
      File file = du.getFile();
      File parent = file.getParentFile();
      if (parent == null) return;
      
      String fullName = parent.getName() + "/" + file.getName();
      synchronized (parentDUMap)
      {
         parentDUMap.put(fullName, du);
      }

      try
      {
         // We check if we must do a remote call or not: maybe the deploy 
         // is already the consequence of a farm call! (avoid recusivity!)
         //
         boolean consequenceOfRemoteCall = false;
         synchronized (remotelyDeployed)
         {
            consequenceOfRemoteCall = remotelyDeployed.remove (fullName);
         }
         
         if (getState() == STARTING) return;

         if (!consequenceOfRemoteCall)
         {
            Date fileDate = new Date(file.lastModified());
            HAPartition lHAPartition = (HAPartition) mServer.getAttribute(
               mClusterPartitionName,
               "HAPartition"
               );
            this.mFileTransfer.push(file, parent.getName(), true);

            lHAPartition.callMethodOnCluster(
               SERVICE_NAME,
               "farmDeploy",
               new Object[] {parent.getName(), file, fileDate},
               new Class[] {String.class, File.class, Date.class},
               true
               );
         }
      }
      catch (ClusterFileTransferException e)
      {
         logException(e);
      }
      catch (Exception ex)
      {
         logException(ex);
      }

   
public voidfarmDeploy(java.lang.String parentName, java.io.File destFile, java.util.Date date)

      try 
      {
         File parent = findParent(parentName);
         if (parent == null) 
         {
            log.info("Could not find parent: " + parentName + " for deployment: " + destFile + ", data: " + date);
            return;
         }
         
         String fullName = parentName + "/" + destFile.getName();

         DeployedURL du = null;
         synchronized(parentDUMap)
         {
            du = (DeployedURL)parentDUMap.get(fullName);
         }
         boolean deployIt = false;
         if (du == null) 
         {
            deployIt = true;
         }
         else
         {
            Date lastChanged = new Date(du.getFile().lastModified());
            deployIt = lastChanged.before(date);
         }

         if (deployIt)
         {
            // we remember this deployment to avoid recursive farm calls!
            //
            synchronized (remotelyDeployed)
            {
               remotelyDeployed.add (fullName);
            }

            log.info( "farmDeployment(), deploy locally: " + fullName );
            // Adjust the date and move the file to /farm
            // but delete it first if already there
            File tempFile = new File(this.mTempDirectory, destFile.getName() );
            File lFarmFile = new File(parent,destFile.getName());
            if( lFarmFile.exists() ) {
               if(!lFarmFile.delete()) {
                  log.info("could not delete target file for farm deployment "+ lFarmFile.getName());
               }
            }
            tempFile.setLastModified( date.getTime() );

            if(! ClusterFileTransfer.localMove(tempFile,lFarmFile ))
            {
               log.info("Could not move "+tempFile+" to " + lFarmFile);
            }
         }
         else
         {
            log.info(fullName + " is already deployed by farm service on this node");
         }
      }
      catch( Exception e ) {
         logException( e );
      }
   
public java.util.HashMapfarmDeployments()

      log.debug("farmDeployments request, parentDUMap.size="+parentDUMap.size());
      Iterator it = parentDUMap.keySet().iterator();
      HashMap farmed = new HashMap();
      while(it.hasNext())
      {
         String key = (String)it.next();
         DeployedURL du = (DeployedURL)parentDUMap.get(key);
         farmed.put(key, new Date(du.getFile().lastModified()));
      }
      return farmed;
   
public voidfarmUndeploy(java.lang.String parentName, java.lang.String fileName)

      try {
         // First check if file is already deployed
         log.info( "doUndeployment(), File: " + parentName + "/" + fileName);
         File parent = findParent(parentName);
         if (parent == null) 
         {
            log.info("Could not find parent: " + parentName + " for undeployment: " + fileName);
            return;
         }
         File deployed = new File(parent, fileName);
         if (deployed.exists())
         {            
            // we remember this undeployment to avoid recursive farm calls!
            //
            synchronized (remotelyUndeployed)
            {
               String fullName = parentName + "/" + fileName;
               remotelyUndeployed.add (fullName);
            }

            if(deployed.delete())
               log.info( "farmUndeployment(), removed file " + deployed );
            else
               log.info( "farmUndeployment(), could not remove file " + deployed );
         }
      }
      catch( Exception e ) {
         logException( e );
      }
   
protected java.io.FilefindParent(java.lang.String parentName)

      URL[] urls = (URL[]) urlList.toArray( new URL[] {} );
      for (int i = 0; i < urlList.size(); i++)
      {
         if (urls[i].getProtocol().equals("file"))
         {
            File file = new File(urls[i].getFile());
            if (file.isDirectory())
            {
               if (file.getName().equals(parentName)) return file;
            }
         }
      }
      return null;
   
public ClusterPartitionMBeangetClusterPartition()

      return mClusterPartition;
   
public java.lang.StringgetName()

      return "Farm Member Service";
   
public java.lang.StringgetPartitionName()


     
   
      return mBackgroundPartition;
   
private voidlogException(java.lang.Throwable e)
Go through the myriad of nested JMX exception to pull out the true exception if possible and log it.

param
e The exception to be logged.

      if (e instanceof javax.management.RuntimeErrorException)
      {
         e = ((javax.management.RuntimeErrorException)e).getTargetError();
      }
      else if (e instanceof javax.management.RuntimeMBeanException)
      {
         e = ((javax.management.RuntimeMBeanException)e).getTargetException();
      }
      else if (e instanceof javax.management.RuntimeOperationsException)
      {
         e = ((javax.management.RuntimeOperationsException)e).getTargetException();
      }
      else if (e instanceof javax.management.MBeanException)
      {
         e = ((javax.management.MBeanException)e).getTargetException();
      }
      else if (e instanceof javax.management.ReflectionException)
      {
         e = ((javax.management.ReflectionException)e).getTargetException();
      }
      
      log.error(e);
   
public javax.management.ObjectNamepreRegister(javax.management.MBeanServer pServer, javax.management.ObjectName pName)
Saves the MBeanServer reference, create the Farm Member Name and add its Notification Listener to listen for Deployment / Undeployment notifications from the {@link org.jboss.deployment.MainDeployer MainDeployer}.

      mServer = pServer;
      return super.preRegister(pServer, pName);
   
protected voidpullNewDeployments(org.jboss.ha.framework.interfaces.HAPartition partition, java.util.HashMap farmed)

      log.info("**** pullNewDeployments ****");
      Iterator it = farmed.keySet().iterator();
      while (it.hasNext())
      {
         String depName = (String)it.next();
         DeployedURL du = (DeployedURL)parentDUMap.get(depName);
         Date last = (Date)farmed.get(depName);
         if (du != null)
         {
            Date theLast = new Date(du.getFile().lastModified());
            if (!theLast.before(last))
            {
               continue;
            }
         }

         String parentName = depName.substring(0, depName.indexOf('/"));
         File destFile = new File(depName);
         try
         {
            mFileTransfer.pull(destFile,parentName);
            synchronized (remotelyDeployed)
            {
               remotelyDeployed.add (destFile.getName());
            }
         }
         catch(ClusterFileTransferException e)
         {
            // log the exception and continue with the next deployment
            this.logException(e);
         }
      }
   
public voidsetClusterPartition(ClusterPartitionMBean clusterPartition)

      if( ( getState () != STARTED ) && ( getState () != STARTING ) )   
      {         
         this.mClusterPartition = clusterPartition;
      }
   
public voidsetDeployer(javax.management.ObjectName deployerName)

      super.setDeployer(deployerName);
      
      // Cache the deployer name so we can reset it in case of restart
      this.mDeployerName = deployerName;
   
public voidsetFarmDeployDirectory(java.lang.String urls)
Backward compatibility, mapped to the URLs attribute of URLDeploymentScannerMBean

deprecated

      super.setURLs(urls);
   
public voidsetPartitionName(java.lang.String pPartitionName)

      if( ( getState () != STARTED ) && ( getState () != STARTING ) )
      {
         mBackgroundPartition = pPartitionName;
      }
   
public voidsetScannerName(java.lang.String name)
Backward compatibility, but ignored as it does nothing.

deprecated

      log.warn("ScannerName does nothing");
   
protected voidstartService()
Register itself as RPC-Handler to the HA-Partition and add the farm deployment directory to the scanner

      try
      {
         log.debug( "registerRPCHandler" );
         
         HAPartition lHAPartition = null;
         if (mClusterPartition != null)
         {
            lHAPartition = mClusterPartition.getHAPartition();
            mBackgroundPartition = lHAPartition.getPartitionName();
         }
         
         mClusterPartitionName = new ObjectName( "jboss:service=" + mBackgroundPartition );
         
         if (lHAPartition == null)
         {
            // Old style config with PartitionName was used -- have to
            // look up the partition in JMX
            lHAPartition = (HAPartition) mServer.getAttribute(
               mClusterPartitionName,
               "HAPartition"
            );
         }
         
         lHAPartition.registerRPCHandler( SERVICE_NAME, this );

         mFileTransfer = new ClusterFileTransfer(lHAPartition, buildParentFolderMapping());

         ArrayList response = lHAPartition.callMethodOnCoordinatorNode(
            SERVICE_NAME,
            "farmDeployments",
            new Object[] {}, new Class[] {},
            true
         );

         log.debug("Found "+response.size()+" farmDeployments responses");
         for (int i = 0; i < response.size(); i++)
         {
            Object map = response.get(i);
            if ( map != null && map instanceof HashMap )
            {
               HashMap farmed = (HashMap) map;
               pullNewDeployments(lHAPartition, farmed);
            }
         }

         // scan before we enable the thread, so JBoss version shows up afterwards
         scannerThread.doScan();

         // enable scanner thread if we are enabled
         scannerThread.setEnabled(isScanEnabled());
      }
      catch(Exception e)
      {
         this.logException(e);
         throw e;
      }
   
protected voidundeploy(DeployedURL du)

      
      File file = du.getFile();
      File parent = file.getParentFile();
      String parentName = parent.getName();
      String fileName = file.getName();
      super.undeploy(du);
      
      String fullName = parent.getName() + "/" + file.getName();
      synchronized (parentDUMap)
      {
         parentDUMap.remove(fullName);
      }
      
      if (getState() == STOPPING) return;

      try
      {
         // We check if we must do a remote call or not: maybe the undeploy 
         // is already the consequence of a farm call! (avoid recusivity!)
         //
         boolean consequenceOfRemoteCall = false;
         synchronized (remotelyUndeployed)
         {
            consequenceOfRemoteCall = remotelyUndeployed.remove (fullName);
         }
         
         if (!consequenceOfRemoteCall)
         {
            HAPartition lHAPartition = (HAPartition) mServer.getAttribute(
               mClusterPartitionName,
               "HAPartition"
               );
            lHAPartition.callMethodOnCluster(
               SERVICE_NAME,
               "farmUndeploy",
               new Object[] {parentName, fileName},
               new Class[] {String.class, String.class},
               true
               );
         }
      }
      catch (Exception ex)
      {
         logException(ex);
      }