com.sun.jbi.management.system.AutoAdminTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of manage Show documentation
Show all versions of manage Show documentation
JBI Runtime Management components, providing installation, deployment, and other JMX interfaces for
remote management consoles.
/*
* BEGIN_HEADER - DO NOT EDIT
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* If applicable add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced with
* your own identifying information: Portions Copyright
* [year] [name of copyright owner]
*/
/*
* @(#)AutoAdminTask.java
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
*
* END_HEADER - DO NOT EDIT
*/
package com.sun.jbi.management.system;
import com.sun.jbi.JBIProvider;
import com.sun.jbi.StringTranslator;
import com.sun.jbi.management.config.DeploymentConfigurationFactory;
import com.sun.jbi.management.config.InstallationConfigurationFactory;
import com.sun.jbi.management.LocalStringKeys;
import com.sun.jbi.management.MBeanNames;
import com.sun.jbi.management.repository.Archive;
import com.sun.jbi.management.repository.ArchiveType;
import com.sun.jbi.ui.common.JBIManagementMessage;
//import com.sun.org.apache.xpath.internal.XPathAPI;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileOutputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jbi.management.DeploymentServiceMBean;
import javax.management.ObjectName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
/**
* This is the JBI Framework Auto Admin Task, which helps with autodeploy and
* autoinstall functionality.
*
* @author Sun Microsystems, Inc.
*/
public class AutoAdminTask
{
/** Root directory for autoinstall. */
public static final String AUTOINSTALL_DIR = "autoinstall";
/** Working directory for installer. */
private static final String INSTALL_STATUS_DIR = ".autoinstallstatus";
/** File name suffix for a successful autoinstall operation. */
private static final String INSTALL_SUCCESS = "_installed";
/** File name suffix for an unsuccessful autoinstall operation. */
private static final String INSTALL_FAILURE = "_notInstalled";
/** File name suffix for a successful autouninstall operation. */
private static final String UNINSTALL_SUCCESS = "_uninstalled";
/** File name suffix for an unsuccessful autouninstall operation. */
private static final String UNINSTALL_FAILURE = "_notUninstalled";
/** Root directory for autodeploy. */
public static final String AUTODEPLOY_DIR = "autodeploy";
/** Working directory for deployer. */
private static final String DEPLOY_STATUS_DIR = ".autodeploystatus";
/** File name suffix for a successful autodeploy operation. */
private static final String DEPLOY_SUCCESS = "_deployed";
/** File name suffix for an unsuccessful autodeploy operation. */
private static final String DEPLOY_FAILURE = "_notDeployed";
/** File name suffix for a successful autoundeploy operation. */
private static final String UNDEPLOY_SUCCESS = "_undeployed";
/** File name suffix for an unsuccessful autoundeploy operation. */
private static final String UNDEPLOY_FAILURE = "_notUndeployed";
/** Separates the autodeployed file's name from the SA name */
public static final String DELIMITER = "--";
/** Separates the autoinstalled file's name from the component's name */
public static final String COMP_DELIMITER = DELIMITER + "comp" + DELIMITER;
/** Separates the autoinstalled file's name from the shared library's name */
public static final String SL_DELIMITER = DELIMITER + "sl" + DELIMITER;
/**
* Management context
*/
private ManagementContext mContext;
//where to log messages:
private Logger mLogger;
// Directory from where JBI picks up installable jars
private File mAutoInstallDir;
private String mAutoInstallDirName;
// Directory from where JBI picks up deployable zips
private File mAutoDeployDir;
private String mAutoDeployDirName;
// Work directory for installation (where timestamps and associations are kept)
private File mInstallTimestampsDir;
// Work directory for deployment (where timestamps and associations are kept)
private File mDeployTimestampsDir;
//DocumentBuilder
private DocumentBuilder mDocBuilder;
/** is auto install currently enabled? */
private boolean mAutoInstallEnabled;
/** is auto reinstall currently enabled? */
private boolean mAutoReinstallEnabled;
/** is auto uninstall currently enabled? */
private boolean mAutoUninstallEnabled;
/** is auto deploy currently enabled? */
private boolean mAutoDeployEnabled = false; // always false for Glassfish
/** is auto redeploy currently enabled? */
private boolean mAutoRedeployEnabled;
/** is auto undeploy currently enabled? */
private boolean mAutoUndeployEnabled;
/** ObjectName for InstallationService */
private ObjectName mInstallationMBean;
/** ObjectName for DeploymentService */
private ObjectName mDeploymentMBean;
/** ObjectName for Installation ConfigurationService */
private ObjectName mInstallConfigSvcMBean;
/** ObjectName for Deployment ConfigurationService */
private ObjectName mDeployConfigSvcMBean;
/**
* Handle to StringTranslator for message translation
*/
private StringTranslator mTranslator;
/**
* The three different types of query for the pollAutoDirectory function
*/
public enum PollFunction
{
NEW_FILES,
DELETED_FILES,
UPDATED_FILES
}
/**
* Filters out all status files except for those starting with the given prefix.
*/
private class NamedFileFinder implements FilenameFilter {
String prefix = null;
NamedFileFinder(String p) {
prefix = p;
}
public boolean accept(File dir, String name) {
if (name.startsWith(prefix + DELIMITER)) {
return true;
}
return false;
}
}
/**
* Constructs a AutoAdminTask.
* @param anEnv is the ManagementContext.
*/
public AutoAdminTask (ManagementContext anEnv)
{
mContext = anEnv;
mLogger = mContext.getLogger();
mTranslator = (StringTranslator) anEnv.getEnvironmentContext().
getStringTranslator("com.sun.jbi.management");
// Autoinstall and Autodeploy always target the local instance
mInstallationMBean = mContext.getMBeanNames().getSystemServiceMBeanName(
MBeanNames.ServiceName.InstallationService,
MBeanNames.ServiceType.Installation,
mContext.getEnvironmentContext().getPlatformContext().getInstanceName());
mDeploymentMBean = mContext.getMBeanNames().getSystemServiceMBeanName(
MBeanNames.ServiceName.DeploymentService,
MBeanNames.ServiceType.Deployment,
mContext.getEnvironmentContext().getPlatformContext().getInstanceName());
mInstallConfigSvcMBean = mContext.getMBeanNames().getSystemServiceMBeanName(
MBeanNames.ServiceName.ConfigurationService,
MBeanNames.ServiceType.Installation,
mContext.getEnvironmentContext().getPlatformContext().getInstanceName());
mDeployConfigSvcMBean = mContext.getMBeanNames().getSystemServiceMBeanName(
MBeanNames.ServiceName.ConfigurationService,
MBeanNames.ServiceType.Deployment,
mContext.getEnvironmentContext().getPlatformContext().getInstanceName());
}
/**
* Constructs a AutoAdminTask for use by junit tests.
* @param anEnv is the ManagementContext.
* @param autoInstallDir Directory for auto install dir
* @param autoDeployDir Directory for auto deploy dir
* @param isAutoInstallEnabled true iff the auto install permission bit set.
* @param isAutoDeployEnabled true iff the auto deploy permission bit set.
*/
public AutoAdminTask (ManagementContext anEnv,
String aDirectoryForAutoInstall,
String aDirectoryForAutoDeploy,
boolean isAutoInstallEnabled,
boolean isAutoDeployEnabled)
{
this(anEnv);
mAutoInstallDirName = aDirectoryForAutoInstall;
mAutoDeployDirName = aDirectoryForAutoDeploy;
mAutoInstallEnabled = isAutoInstallEnabled;
mAutoReinstallEnabled = isAutoInstallEnabled;
mAutoUninstallEnabled = isAutoInstallEnabled;
mAutoDeployEnabled = isAutoDeployEnabled;
mAutoRedeployEnabled = isAutoDeployEnabled;
mAutoUndeployEnabled = isAutoDeployEnabled;
}
/**
* Process autoinstall and autodeploy directories.
* @throws Exception unexpectedly.
*/
public synchronized void performAutoFunctions()
throws Exception
{
// for efficiency, check configuration settings once per heartbeat
mAutoInstallDirName = getConfigAttribute(mInstallConfigSvcMBean,
InstallationConfigurationFactory.AUTO_INSTALL_DIR);
mAutoDeployDirName = getConfigAttribute(mDeployConfigSvcMBean,
DeploymentConfigurationFactory.AUTO_DEPLOY_DIR);
mAutoInstallEnabled = checkConfigPermission(mInstallConfigSvcMBean,
InstallationConfigurationFactory.ENABLE_AUTO_INSTALL);
mAutoReinstallEnabled = checkConfigPermission(mInstallConfigSvcMBean,
InstallationConfigurationFactory.ENABLE_AUTO_REINSTALL);
mAutoUninstallEnabled = checkConfigPermission(mInstallConfigSvcMBean,
InstallationConfigurationFactory.ENABLE_AUTO_UNINSTALL);
// Glassfish handles autodeploy on its own
if (mContext.getEnvironmentContext().getProvider() != JBIProvider.SUNAS)
{
mAutoDeployEnabled = checkConfigPermission(mDeployConfigSvcMBean,
DeploymentConfigurationFactory.ENABLE_AUTO_DEPLOY);
mAutoRedeployEnabled = checkConfigPermission(mDeployConfigSvcMBean,
DeploymentConfigurationFactory.ENABLE_AUTO_REDEPLOY);
mAutoUndeployEnabled = checkConfigPermission(mDeployConfigSvcMBean,
DeploymentConfigurationFactory.ENABLE_AUTO_UNDEPLOY);
}
initDirectories(mAutoInstallEnabled, mAutoDeployEnabled);
if (mAutoInstallEnabled)
{
performAutoInstall();
// only perform autouninstall if autoinstall is also enabled
if (mAutoUninstallEnabled)
{
performAutoUninstall();
// only perform autoreinstall if autoinstall and autouninstall
// are also enabled
if (mAutoUninstallEnabled)
{
performAutoReinstall();
}
}
}
if (mAutoDeployEnabled)
{
performAutoDeploy();
// only perform autoundeploy if autodeploy is also enabled
if (mAutoUndeployEnabled)
{
performAutoUndeploy();
// only perform autoredeploy if autodeploy and autoundeploy
// are also enabled
if (mAutoRedeployEnabled)
{
performAutoRedeploy();
}
}
}
}
/**
* Process autoinstall directory for new files.
* @throws Exception unexpectedly.
*/
public void performAutoInstall()
{
File installFile;
while ((installFile =
pollAutoDirectory(PollFunction.NEW_FILES,
mAutoInstallDir, mInstallTimestampsDir)) != null)
{
doInstall(installFile);
}
}
/**
* Routine called by both performAutoInstall() and performAutoReinstall()
* to do the installation of a specific component file.
* @param installFile the File to install.
*/
private void doInstall(File installFile)
{
Archive installArchive;
String componentName;
try
{
// create timestamp for this file -- copy time from existing one
String fileName = installFile.getName();
File timeStamp = new File(mInstallTimestampsDir, fileName);
timeStamp.createNewFile();
timeStamp.setLastModified(installFile.lastModified());
installArchive = new Archive(installFile, true);
if (installArchive.getType().equals(ArchiveType.COMPONENT))
{
componentName = installComponent(installFile.getAbsolutePath());
// store the name in an empty file
File storedNameFile = new File (mInstallTimestampsDir,
fileName + COMP_DELIMITER + componentName);
if (null != componentName)
{
storedNameFile.createNewFile();
storedNameFile.setLastModified(installFile.lastModified());
}
}
else if (installArchive.getType().equals(ArchiveType.SHARED_LIBRARY))
{
componentName = installSharedLibrary(installFile.getAbsolutePath());
// store the name in an empty file
File storedNameFile = new File (mInstallTimestampsDir,
fileName + SL_DELIMITER + componentName);
if (null != componentName)
{
storedNameFile.createNewFile();
storedNameFile.setLastModified(installFile.lastModified());
}
}
else if (installArchive.getType().equals(ArchiveType.SERVICE_ASSEMBLY))
{
removeInstallLogs(installFile.getAbsolutePath());
writeLog(installFile.getAbsolutePath() + INSTALL_FAILURE,
mTranslator.getString(LocalStringKeys.AA_DEPLOY_NOT_SUPPORTED));
}
}
catch (Exception ex)
{
removeInstallLogs(installFile.getAbsolutePath());
writeLog(installFile.getAbsolutePath() + INSTALL_FAILURE, ex.toString());
}
}
/**
* Process autodeploy directory for new files.
* @throws Exception unexpectedly.
*/
public void performAutoDeploy()
{
File deployFile;
while ((deployFile =
pollAutoDirectory(PollFunction.NEW_FILES,
mAutoDeployDir, mDeployTimestampsDir)) != null)
{
doDeploy(deployFile);
}
}
/**
* Routine called by both performAutoDeploy() and performAutoRedeploy()
* to do the deployment of a specific service assembly
* @param deployFile the File to install.
*/
private void doDeploy(File deployFile)
{
Archive deployArchive;
String componentName;
try
{
// create timestamp for this file -- copy time from existing one
String fileName = deployFile.getName();
File timeStamp = new File(mDeployTimestampsDir, fileName);
timeStamp.createNewFile();
timeStamp.setLastModified(deployFile.lastModified());
deployArchive = new Archive(deployFile, true);
if (deployArchive.getType().equals(ArchiveType.SERVICE_ASSEMBLY))
{
String serviceAssemblyName = deployArchive.getJbiName();
deployServiceAssembly(serviceAssemblyName,
deployFile.getAbsolutePath());
// store the name in an empty file
File storedNameFile = new File (mDeployTimestampsDir,
fileName + DELIMITER + serviceAssemblyName);
if (null != storedNameFile)
{
storedNameFile.createNewFile();
storedNameFile.setLastModified(deployFile.lastModified());
}
}
else
{
removeDeployLogs(deployFile.getAbsolutePath());
writeLog(deployFile.getAbsolutePath() + DEPLOY_FAILURE,
mTranslator.getString(LocalStringKeys.AA_INSTALL_NOT_SUPPORTED));
}
}
catch (Exception ex)
{
removeDeployLogs(deployFile.getAbsolutePath());
writeLog(deployFile.getAbsolutePath() + DEPLOY_FAILURE, ex.toString());
}
}
/**
* Process autoinstall directory for deleted files.
* @throws Exception unexpectedly.
*/
public void performAutoUninstall()
{
File deletedFile;
while ((deletedFile =
pollAutoDirectory(PollFunction.DELETED_FILES,
mAutoInstallDir, mInstallTimestampsDir)) != null)
{
doUninstall(deletedFile);
}
}
/**
* Routine called by both performAutoUninstall() and performAutoReinstall()
* to do the uninstallation of a specific component file.
* @param deletedFile the File to uninstall.
* @returns true iff the uninstall was successful.
*/
private boolean doUninstall(File deletedFile)
{
String fileName = null;
try
{
// delete timestamp for this file
fileName = deletedFile.getName();
mLogger.log(Level.FINER, "doUninstall() deleting file {0}", fileName);
deletedFile.delete();
// find the file (if present) that specified if this was a
// shared library or component, and what its name was.
for (File deletedData : mInstallTimestampsDir.listFiles(
new NamedFileFinder(fileName)))
{
deletedData.delete();
mLogger.log(Level.FINER, "doUninstall() on {0}", deletedData.getName());
String cSuffix = suffix(deletedData.getName(), fileName + COMP_DELIMITER);
String slSuffix = suffix(deletedData.getName(), fileName + SL_DELIMITER);
if (null != cSuffix)
{
uninstallComponent(cSuffix);
}
if (null != slSuffix)
{
uninstallSharedLibrary(slSuffix);
}
}
// put new log file in mAutoInstallDir, not timestamp dir.
fileName = mAutoInstallDir.getAbsolutePath() + File.separator + fileName;
removeInstallLogs(fileName);
writeLog(fileName + UNINSTALL_SUCCESS, "");
return true;
}
catch (Exception ex)
{
if (null != fileName)
{
// put new log file in mAutoInstallDir, not timestamp dir.
fileName = mAutoInstallDir.getAbsolutePath() +
File.separator + fileName;
removeInstallLogs(fileName);
writeLog(fileName + UNINSTALL_FAILURE, ex.toString());
}
return false;
}
}
/**
* Process autodeploy directory for deleted files.
* @throws Exception unexpectedly.
*/
public void performAutoUndeploy()
{
File deletedFile;
while ((deletedFile =
pollAutoDirectory(PollFunction.DELETED_FILES,
mAutoDeployDir, mDeployTimestampsDir)) != null)
{
doUndeploy(deletedFile);
}
}
/**
* Routine called by both performAutoUndeploy() and performAutoRedeploy()
* to do the undeployment of a specific service assembly.
* @param deletedFile the File to undeploy.
* @returns true iff the undeploy was successful.
*/
private boolean doUndeploy(File deletedFile)
{
String fileName = null;
boolean results = true;
try
{
// delete timestamp for this file
fileName = deletedFile.getName();
mLogger.log(Level.FINER, "doUndeploy() deleting file {0}", fileName);
deletedFile.delete();
// find the file (if present) that specified
// the name of the deployed service assembly.
for (File deletedData : mDeployTimestampsDir.listFiles(
new NamedFileFinder(fileName)))
{
deletedData.delete();
mLogger.log(Level.FINER, "doUndeploy() on {0}", deletedData.getName());
String saName = suffix(deletedData.getName(), fileName + DELIMITER);
if (null != saName)
{
results = undeployServiceAssembly(saName);
}
}
// put new log file in mAutoDeployDir, not timestamp dir.
fileName = mAutoDeployDir.getAbsolutePath() + File.separator + fileName;
removeDeployLogs(fileName);
writeLog(fileName + UNDEPLOY_SUCCESS, "");
return results;
}
catch (Exception ex)
{
if (null != fileName)
{
// put new log file in mAutoDeployDir, not timestamp dir.
fileName = mAutoDeployDir.getAbsolutePath() +
File.separator + fileName;
removeDeployLogs(fileName);
writeLog(fileName + UNDEPLOY_FAILURE, ex.toString());
}
return false;
}
}
/**
* Process autoinstall directory for updated files.
* @throws java.io.IOException unexpectedly.
*/
public void performAutoReinstall()
throws java.io.IOException
{
File updatedFile;
while ((updatedFile =
pollAutoDirectory(PollFunction.UPDATED_FILES,
mAutoInstallDir, mInstallTimestampsDir)) != null)
{
String fileName = updatedFile.getName();
File timeStamp = new File(mInstallTimestampsDir, fileName);
if (doUninstall(timeStamp))
{
doInstall(updatedFile);
}
else
{
// change the timestamp of our status file so that we do not
// try to install the new version of the file
timeStamp.createNewFile(); // it was deleted by doUninstall().
timeStamp.setLastModified(updatedFile.lastModified());
}
}
}
/**
* Process autodeploy directory for updated files.
* @throws java.io.IOException unexpectedly.
*/
public void performAutoRedeploy()
throws java.io.IOException
{
File updatedFile;
while ((updatedFile =
pollAutoDirectory(PollFunction.UPDATED_FILES,
mAutoDeployDir, mDeployTimestampsDir)) != null)
{
String fileName = updatedFile.getName();
File timeStamp = new File(mDeployTimestampsDir, fileName);
if (doUndeploy(timeStamp))
{
doDeploy(updatedFile);
}
else
{
// change the timestamp of our status file so that we do not
// try to deploy the new version of the file
timeStamp.createNewFile(); // it was deleted by doUndeploy().
timeStamp.setLastModified(updatedFile.lastModified());
}
}
}
/**
* Routine to parse the result of an install or deploy operation.
* @param aResultString the task result result to parse.
* @return true iff the task was executed successfully.
*
*/
private boolean parseResultAsSuccess(String aResultString)
{
Document doc;
Text resultText;
try
{
doc = getDocument(new InputSource((new StringReader(aResultString))));
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
XPathExpression xpathExpr = xpath.compile(
"jbi-task/jbi-task-result/frmwk-task-result/" +
"frmwk-task-result-details/task-result-details/task-result");
resultText = (Text) ((NodeList) xpathExpr.evaluate(doc, XPathConstants.NODESET)).item(0).getFirstChild();
return ("SUCCESS".equalsIgnoreCase(resultText.getData().trim()));
}
catch(Throwable t)
{
// by default, consider the operation as a failure.
t.printStackTrace();
return false;
}
}
/** Synchronized wrapper for non-thread-safe JAXP DocumentBuilder. */
private synchronized Document getDocument(InputSource source)
throws Exception
{
if (mDocBuilder == null)
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
mDocBuilder = dbf.newDocumentBuilder();
}
return mDocBuilder.parse(source);
}
/** Install a component.
* @param location path to the component installation archive
* @return the name of the component
*/
private String installComponent(String location)
{
ObjectName installerMBean;
ObjectName lifecycleMBean = null;
String compId = null;
String errorMsg = "";
boolean installSuccessful;
// Autoinstall consists of two phases:
// Phase 1: installation
// Phase 2: installer clean-up and starting the installed component
// A failure is phase 1 is considered a failed installation. A failure
// in phase 2 is considered a success, but any error information is
// included in the success log file.
// Phase 1: installation
try
{
// load the component's installer MBean
installerMBean = (ObjectName)mContext.getMBeanServer().invoke(
mInstallationMBean, "loadNewInstaller",
new Object[] {location},
new String[] {"java.lang.String"});
// get the component id
compId = installerMBean.getKeyProperty(
mContext.getMBeanNames().COMPONENT_ID_KEY);
// install the component using its installer MBean
lifecycleMBean = (ObjectName)mContext.getMBeanServer().invoke(
installerMBean, "install",
new Object[] {}, new String[] {});
installSuccessful = true;
}
catch (Exception ex)
{
installSuccessful = false;
errorMsg = ex.getMessage();
}
// Phase 2: clean-up and start
try
{
// If the installer was loaded, we need to clean it up
if (compId != null)
{
mContext.getMBeanServer().invoke(
mInstallationMBean, "unloadInstaller",
new Object[] {compId, !installSuccessful},
new String[] {"java.lang.String", "boolean"});
}
// Only start the component if the installation was successful
if (installSuccessful && lifecycleMBean != null)
{
mContext.getMBeanServer().invoke(
lifecycleMBean, "start",
new Object[] {}, new String[] {});
}
}
catch (Exception ex)
{
errorMsg = ex.getMessage();
}
removeInstallLogs(location);
writeLog(location + (installSuccessful ? INSTALL_SUCCESS : INSTALL_FAILURE),
errorMsg);
return compId;
}
/** Uninstall a component.
* @param componentName the name of the component to uninstall
* @throws Exception unexpectedly.
*/
private void uninstallComponent(String componentName)
throws Exception
{
ObjectName adminMBean;
ObjectName lifecycleMBean;
ObjectName installerMBean;
adminMBean = mContext.getMBeanNames().getSystemServiceMBeanName(
MBeanNames.ServiceName.AdminService,
MBeanNames.ServiceType.Admin,
mContext.getEnvironmentContext().getPlatformContext().getInstanceName());
// load the component's lifecycle MBean
lifecycleMBean = (ObjectName)mContext.getMBeanServer().invoke(
adminMBean, "getComponentByName",
new Object[] {componentName},
new String[] {"java.lang.String"});
// invoke shutdown on the component lifecycle
if (lifecycleMBean == null)
{
// the component is not installed
mLogger.log(Level.FINER, "No need to autouninstall component {0}, as it has already been uninstalled.", componentName);
return;
}
mContext.getMBeanServer().invoke(
lifecycleMBean, "shutDown",
new Object[] {}, new String[] {});
// create a new installer MBean for the component
installerMBean = (ObjectName)mContext.getMBeanServer().invoke(
mInstallationMBean, "loadInstaller",
new Object[] {componentName},
new String[] {"java.lang.String"});
// invoke uninstall on that MBean
lifecycleMBean = (ObjectName)mContext.getMBeanServer().invoke(
installerMBean, "uninstall",
new Object[] {}, new String[] {});
// now clean up using the unloadInstaller call
mContext.getMBeanServer().invoke(
mInstallationMBean, "unloadInstaller",
new Object[] {componentName, true},
new String[] {"java.lang.String", "boolean"});
}
/** Undeploy a service assembly.
* @param saName the name of the service assembly to undeploy
* @throws Exception unexpectedly.
*/
private boolean undeployServiceAssembly(String saName)
throws Exception
{
String results = null;
String state = "not found";
boolean deployed = getRegistry().getGenericQuery().
isServiceAssemblyDeployed(saName);
if (!deployed)
{
return true;
}
try
{
state = (String) mContext.getMBeanServer().invoke(
mDeploymentMBean, "getState",
new Object[] {saName},
new String[] {"java.lang.String"});
}
catch (Exception e)
{
mLogger.log(Level.FINER, "getState({0}) threw {1}.", new Object[]{saName, e});
return true;
}
// if it's already shut down, don't reshut it down
if (state.equalsIgnoreCase(DeploymentServiceMBean.STARTED) ||
state.equalsIgnoreCase(DeploymentServiceMBean.STOPPED))
{
// shutDown will invoke stop when needed
mContext.getMBeanServer().invoke(
mDeploymentMBean, "shutDown",
new Object[] {saName},
new String[] {"java.lang.String"});
}
results = (String) mContext.getMBeanServer().invoke(
mDeploymentMBean, "undeploy",
new Object[] {saName},
new String[] {"java.lang.String"});
return parseResultAsSuccess(results);
}
/** Install a shared library.
* @param location path to the shared library installation archive
* @return the name of the shared library
*/
private String installSharedLibrary(String location)
{
String slId = null;
try
{
// install the shared library
slId = (String) mContext.getMBeanServer().invoke(
mInstallationMBean, "installSharedLibrary",
new Object[] {location},
new String[] {"java.lang.String"});
removeInstallLogs(location);
writeLog(location + INSTALL_SUCCESS, "");
}
catch (Exception ex)
{
removeInstallLogs(location);
writeLog(location + INSTALL_FAILURE, ex.getMessage());
}
return slId;
}
/** Uninstall a shared library.
* @param slName name of the shared library
* @throws Exception unexpectedly.
*/
private void uninstallSharedLibrary(String slName)
throws Exception
{
boolean installed = getRegistry().getGenericQuery().
isSharedLibraryInstalled(slName);
if (installed)
{
mContext.getMBeanServer().invoke(
mInstallationMBean, "uninstallSharedLibrary",
new Object[] {slName},
new String[] {"java.lang.String"});
}
}
/** Deploy a service assembly.
* @param saName service assembly name
* @param location path to the service assembly archive
*/
private void deployServiceAssembly(String saName, String location)
{
boolean deploySuccessful;
String result;
// Autodeploy consists of two phases:
// Phase 1: deployment
// Phase 2: starting the deploy service assembly
// A failure is phase 1 is considered a failed deployment. A failure
// in phase 2 is considered a success, but any error information is
// included in the success log file.
// Phase 1: deployment
try
{
// deploy the service assembly
result = (String)mContext.getMBeanServer().invoke(
mDeploymentMBean, "deploy",
new Object[] {location},
new String[] {"java.lang.String"});
deploySuccessful = parseResultAsSuccess(result);
}
catch (Exception ex)
{
deploySuccessful = false;
result = ex.getMessage();
}
// Phase 2: start the assembly
if (deploySuccessful)
{
try
{
result = (String)mContext.getMBeanServer().invoke(
mDeploymentMBean, "start",
new Object[] {saName},
new String[] {"java.lang.String"});
}
catch (Exception ex)
{
result = ex.getMessage();
}
}
removeDeployLogs(location);
writeLog(location + (deploySuccessful ? DEPLOY_SUCCESS : DEPLOY_FAILURE),
result);
}
/** Creates a log file with the specified message. The caller is
* responsible for creating a path with a .success or .failed suffix
* consistent with the content of the message.
*/
private void writeLog(String path, String message)
{
FileOutputStream fos = null;
JBIManagementMessage prettyMessage =
JBIManagementMessage.createJBIManagementMessage(message);
// use JBIManagementMessage to pretty print the XML (if possible)
if (prettyMessage != null)
{
message = prettyMessage.getMessage();
}
try
{
fos = new FileOutputStream(path);
fos.write(message.getBytes());
fos.flush();
}
catch (java.io.IOException ioEx)
{
ioEx.printStackTrace();
}
finally
{
if (fos != null)
{
try { fos.close(); }
catch (Exception ex) {}
}
}
}
/** Checks the autoinstall or autodeploy directory for candidate files. If a
* file is found, we check the file suffix (to make sure we are not trying
* to install or deploy a status file), and we also check that an existing
* timestamp file doesn't already exist, with the same filename.
*
* @param queryType (enum) the type of file we are polling for.
* @param topLevelDir the directory to scan for candidate files.
* @param statusDir the directory for timestamp files (to exclude matches).
* @return a File that is a *not* a status file, nor that already exists
* in the status directory.
*/
synchronized File pollAutoDirectory(PollFunction queryType,
File topLevelDir,
File statusDir)
{
File candidate = null;
if (queryType == PollFunction.NEW_FILES)
{
if (topLevelDir != null && topLevelDir.isDirectory())
{
mLogger.log(Level.FINEST, "pollAutoDirectory(new) called on {0}", topLevelDir);
for (File archive : topLevelDir.listFiles())
{
if (archive.isFile())
{
String fileName = archive.getName();
mLogger.log(Level.FINEST, "pollAutoDirectory(new) Found file: {0}", fileName);
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
mLogger.log(Level.FINEST, "pollAutoDirectory(new): File type of the above is: {0}", fileType);
if (fileType.indexOf("_") == -1)
{
File timeStamp = new File(statusDir, fileName);
if (! timeStamp.exists())
{
mLogger.log(Level.FINER, "pollAutoDirectory(new): Ready to handle {0}", fileName);
candidate = archive;
break;
}
}
}
}
}
}
else if (queryType == PollFunction.DELETED_FILES)
{
if (statusDir != null && statusDir.isDirectory())
{
mLogger.log(Level.FINEST, "pollAutoDirectory(deleted) called on {0}", statusDir);
for (File archive : statusDir.listFiles())
{
if (archive.isFile())
{
String fileName = archive.getName();
mLogger.log(Level.FINEST, "pollAutoDirectory(deleted) Found file: {0}", fileName);
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
mLogger.log(Level.FINEST, "pollAutoDirectory(deleted): File type of the above is: {0}", fileType);
if ((fileType.indexOf("_") == -1) &&
(fileType.indexOf(DELIMITER) == -1))
{
File topFile = new File(topLevelDir, fileName);
if (! topFile.exists())
{
mLogger.log(Level.FINER, "pollAutoDirectory(deleted): Ready to handle {0}", fileName);
candidate = archive;
break;
}
}
}
}
}
}
else if (queryType == PollFunction.UPDATED_FILES)
{
if (topLevelDir != null && topLevelDir.isDirectory())
{
mLogger.log(Level.FINEST, "pollAutoDirectory(updated) called on {0}", topLevelDir);
for (File archive : topLevelDir.listFiles())
{
if (archive.isFile())
{
String fileName = archive.getName();
mLogger.log(Level.FINEST, "pollAutoDirectory(updated) Found file: {0}", fileName);
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
mLogger.log(Level.FINEST, "pollAutoDirectory(updated): File type of the above is: {0}", fileType);
if (fileType.indexOf("_") == -1)
{
File timeStamp = new File(statusDir, fileName);
if (timeStamp.exists() &&
(archive.lastModified() > timeStamp.lastModified()))
{
mLogger.log(Level.FINER, "pollAutoDirectory(updated): Ready to handle {0}", fileName);
candidate = archive;
break;
}
}
}
}
}
}
return candidate;
}
/** Check the Configuration MBean for the specified Boolean property.
* @param aConfigSvcName the name of the config service MBean to query.
* @param aPermissionName is the name of the attribute to examine.
* @return "true" or "false" as found in the attribute.
*/
boolean checkConfigPermission(ObjectName aConfigSvcName, String aPermissionName)
{
try
{
// Query configuration server for permission bit.
Object attr = mContext.getMBeanServer().getAttribute(
aConfigSvcName, aPermissionName);
return ((Boolean) attr);
}
catch (Exception e)
{
mLogger.log(Level.FINER, "checkConfigPermission({0}, {1}) returned {2}. Returning default ''false'' value.", new Object[]{aConfigSvcName, aPermissionName, e});
return false;
}
}
/** Check the Configuration MBean for the specified String property.
* @param aConfigSvcName the name of the config service MBean to query.
* @param anAttributeName is the name of the attribute to examine.
* @return the String value from the Configuration MBean attribute.
*/
String getConfigAttribute(ObjectName aConfigSvcName, String anAttributeName)
{
try
{
Object attr = mContext.getMBeanServer().getAttribute(
aConfigSvcName, anAttributeName);
return (String) attr;
}
catch (Exception e)
{
mLogger.log(Level.FINER, "checkConfigPermission({0}, {1}) returned {2}. Returning default ''null'' value.", new Object[]{aConfigSvcName, anAttributeName, e});
return null;
}
}
/** Initializes autoinstall and autodeploy directories.
* @param isAutoInstallEnabled true iff the auto install permission bit set.
* @param isAutoDeployEnabled true iff the auto deploy permission bit set.
*/
void initDirectories(boolean isAutoInstallEnabled, boolean isAutoDeployEnabled)
{
// make sure all required directories exist
if (isAutoInstallEnabled)
{
if (null != mAutoInstallDirName)
{
if (mAutoInstallDirName.startsWith(File.separator) ||
":".equals(mAutoInstallDirName.substring(1,2))) // C:/blah/blah
{
// treat the directory as an absolute path
mAutoInstallDir = new File(mAutoInstallDirName);
}
else // test it as a relative path from the jbi install root
{
mAutoInstallDir = new File(mContext.getJbiInstallRoot(),
mAutoInstallDirName);
}
mInstallTimestampsDir = new File(mAutoInstallDir, INSTALL_STATUS_DIR);
if (! mInstallTimestampsDir.exists())
{
mLogger.log(Level.FINE, "initDirectories() creating {0}", mInstallTimestampsDir);
mInstallTimestampsDir.mkdirs();
}
}
}
// make sure all required directories exist
if (isAutoDeployEnabled)
{
if (null != mAutoDeployDirName)
{
if (mAutoDeployDirName.startsWith(File.separator) ||
":".equals(mAutoDeployDirName.substring(1,2))) // C:/blah/blah
{
// treat the directory as an absolute path
mAutoDeployDir = new File(mAutoDeployDirName);
}
else // test it as a relative path from the jbi install root
{
mAutoDeployDir = new File(mContext.getJbiInstallRoot(),
mAutoDeployDirName);
}
mDeployTimestampsDir = new File(mAutoDeployDir, DEPLOY_STATUS_DIR);
if (! mDeployTimestampsDir.exists())
{
mLogger.log(Level.FINE, "initDirectories() creating {0}", mDeployTimestampsDir);
mDeployTimestampsDir.mkdirs();
}
}
}
}
/**
* Return the suffix of the string (that comes after the prefix)
* @param anInputString the string to return the suffix from
* @param aPrefix the prefix to remove
* @return the string starting after the prefix
*/
private String suffix(String anInputString, String aPrefix)
{
String[] splitNames = anInputString.split(aPrefix, 2);
try
{
return splitNames[1];
}
catch (java.lang.ArrayIndexOutOfBoundsException aioobe)
{
mLogger.log(Level.FINER, "suffix({0}, {1}) threw {2}", new Object[]{anInputString, aPrefix, aioobe});
return null;
}
}
/**
* Remove all old install logs, in preparation for a new log to be written.
* @param location the filename to base the log name on.
*/
private void removeInstallLogs(String location)
{
try
{
File f1 = new File(location + INSTALL_SUCCESS);
File f2 = new File(location + INSTALL_FAILURE);
File f3 = new File(location + UNINSTALL_SUCCESS);
File f4 = new File(location + UNINSTALL_FAILURE);
f1.delete();
f2.delete();
f3.delete();
f4.delete();
}
catch (Exception e)
{
mLogger.log(Level.FINER, "removeInstallLogs({0}) threw {1}", new Object[]{location, e});
}
}
/**
* Remove all old deploy logs, in preparation for a new log to be written.
* @param location the filename to base the log name on.
*/
private void removeDeployLogs(String location)
{
try
{
File f1 = new File(location + DEPLOY_SUCCESS);
File f2 = new File(location + DEPLOY_FAILURE);
File f3 = new File(location + UNDEPLOY_SUCCESS);
File f4 = new File(location + UNDEPLOY_FAILURE);
f1.delete();
f2.delete();
f3.delete();
f4.delete();
}
catch (Exception e)
{
mLogger.log(Level.FINER, "removeDeployLogs({0}) threw {1}", new Object[]{location, e});
}
}
/**
* Get a handle to the registry
*
* @return the persisted registry instance
*/
private com.sun.jbi.management.registry.Registry getRegistry()
{
return (com.sun.jbi.management.registry.Registry) mContext.
getEnvironmentContext().getRegistry();
}
}