/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.gui.admin.plugin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.plugin.*;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.core.gui.util.StringUtility;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.core.util.stream.StreamUtil;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.core.plugin.PluginDeploymentScannerMBean;
import org.rhq.enterprise.server.plugin.ServerPluginManagerLocal;
import org.rhq.enterprise.server.resource.metadata.PluginManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
import org.richfaces.event.UploadEvent;
import javax.faces.application.FacesMessage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.*;
/**
*/
public class InstalledPluginsUIBean {
private final Log log = LogFactory.getLog(InstalledPluginsUIBean.class);
public static final String MANAGED_BEAN_NAME = InstalledPluginsUIBean.class.getSimpleName();
private PluginManagerLocal pluginMgr = LookupUtil.getPluginManager();
private ServerPluginManagerLocal serverPluginsBean = LookupUtil.getServerPluginManager();
public InstalledPluginsUIBean() {
}
public void restartMasterPluginContainer() {
hasPermission();
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
serverPluginsBean.restartMasterPluginContainer(subject);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Master plugin container has been restarted.");
} catch (Exception e) {
processException("Failed to restart the master plugin container", e);
}
return;
}
public Collection<Plugin> getInstalledAgentPlugins() {
hasPermission();
List<Plugin> plugins;
InstalledPluginsSessionUIBean session = FacesContextUtility.getManagedBean(InstalledPluginsSessionUIBean.class);
if (session.isShowAllAgentPlugins()) {
plugins = pluginMgr.getPlugins();
} else {
plugins = pluginMgr.getInstalledPlugins();
}
return sort(plugins);
}
public Collection<ServerPlugin> getInstalledServerPlugins() {
hasPermission();
List<ServerPlugin> plugins;
InstalledPluginsSessionUIBean session = FacesContextUtility.getManagedBean(InstalledPluginsSessionUIBean.class);
if (session.isShowAllServerPlugins()) {
plugins = serverPluginsBean.getAllServerPlugins();
} else {
plugins = serverPluginsBean.getServerPlugins();
}
plugins = sort(plugins);
return plugins;
}
public void scan() {
hasPermission();
try {
PluginDeploymentScannerMBean scanner = LookupUtil.getPluginDeploymentScanner();
scanner.scanAndRegister();
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Done scanning for updated plugins.");
} catch (Exception e) {
processException("Failed to scan for updated plugins", e);
}
}
public void fileUploadListener(UploadEvent event) {
hasPermission();
try {
File uploadedPlugin = event.getUploadItem().getFile();
String newPluginFilename = event.getUploadItem().getFileName();
// some browsers (IE in particular) passes an absolute filename, we just want the name of the file, no paths
if (newPluginFilename != null) {
newPluginFilename = newPluginFilename.replace('\\', '/');
if (newPluginFilename.length() > 2 && newPluginFilename.charAt(1) == ':') {
newPluginFilename = newPluginFilename.substring(2);
}
newPluginFilename = new File(newPluginFilename).getName();
}
log.info("A new plugin [" + newPluginFilename + "] has been uploaded to [" + uploadedPlugin + "]");
if (uploadedPlugin == null || !uploadedPlugin.exists()) {
throw new FileNotFoundException("The uploaded plugin file [" + uploadedPlugin + "] does not exist!");
}
// put the new plugin file in our plugin dropbox location
File installDir = LookupUtil.getCoreServer().getInstallDir();
File dir = new File(installDir, "plugins");
File pluginFile = new File(dir, newPluginFilename);
FileOutputStream fos = new FileOutputStream(pluginFile);
FileInputStream fis = new FileInputStream(uploadedPlugin);
StreamUtil.copy(fis, fos);
log.info("A new plugin has been deployed [" + pluginFile
+ "]. A scan is required now in order to register it.");
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "New plugin uploaded: " + newPluginFilename);
} catch (Exception e) {
processException("Failed to process uploaded plugin", e);
}
return;
}
public void enableAgentPlugins() {
List<Plugin> allSelectedPlugins = getSelectedAgentPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
List<Plugin> pluginsToEnable = new ArrayList<Plugin>();
for (Plugin selectedPlugin : allSelectedPlugins) {
if (!selectedPlugin.isEnabled() && selectedPlugin.getStatus() == PluginStatusType.INSTALLED) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
pluginsToEnable.add(selectedPlugin);
}
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No disabled plugins were selected. Nothing to enable");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
pluginMgr.enablePlugins(subject, getIds(pluginsToEnable));
FacesContextUtility
.addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: " + selectedPluginNames);
} catch (Exception e) {
processException("Failed to enable agent plugins", e);
}
return;
}
public void disableAgentPlugins() {
List<Plugin> allSelectedPlugins = getSelectedAgentPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
List<Plugin> pluginsToDisable = new ArrayList<Plugin>();
for (Plugin selectedPlugin : allSelectedPlugins) {
if (selectedPlugin.isEnabled()) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
pluginsToDisable.add(selectedPlugin);
}
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No enabled plugins were selected. Nothing to disable");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
pluginMgr.disablePlugins(subject, getIds(pluginsToDisable));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Disabled plugins: " + selectedPluginNames);
} catch (Exception e) {
processException("Failed to disable agent plugins", e);
}
return;
}
public void deleteAgentPlugins() {
if (getSelectedPluginIds().length == 0) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No plugins were selected. Nothing to delete");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
List<Plugin> pluginsToDelete = getSelectedAgentPlugins();
List<String> pluginNames = new ArrayList<String>();
for (Plugin plugin : pluginsToDelete) {
pluginNames.add(plugin.getDisplayName());
}
pluginMgr.deletePlugins(subject, Arrays.asList(getSelectedPluginIds()));
PluginDeploymentScannerMBean scanner = LookupUtil.getPluginDeploymentScanner();
scanner.scanAndRegister();
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Deleted plugins: " + pluginNames);
} catch (Exception e) {
processException("Failed to delete agent plugins", e);
}
return;
}
public void enableServerPlugins() {
List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
List<ServerPlugin> pluginsToEnable = new ArrayList<ServerPlugin>();
for (ServerPlugin selectedPlugin : allSelectedPlugins) {
if (!selectedPlugin.isEnabled() && selectedPlugin.getStatus() == PluginStatusType.INSTALLED) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
pluginsToEnable.add(selectedPlugin);
}
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No disabled plugins were selected. Nothing to enable");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
List<PluginKey> enabled = serverPluginsBean.enableServerPlugins(subject, getIds(pluginsToEnable));
if (enabled.size() == pluginsToEnable.size()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: "
+ selectedPluginNames);
} else {
List<String> enabledPlugins = new ArrayList<String>();
List<String> failedPlugins = new ArrayList<String>();
for (ServerPlugin pluginToEnable : pluginsToEnable) {
PluginKey key = PluginKey.createServerPluginKey(pluginToEnable.getType(), pluginToEnable.getName());
if (enabled.contains(key)) {
enabledPlugins.add(pluginToEnable.getDisplayName());
} else {
failedPlugins.add(pluginToEnable.getDisplayName());
}
}
if (enabledPlugins.size() > 0) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Enabled server plugins: "
+ enabledPlugins);
}
if (failedPlugins.size() > 0) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to enable server plugins: "
+ failedPlugins);
}
}
} catch (Exception e) {
processException("Failed to enable server plugins", e);
}
return;
}
public void disableServerPlugins() {
List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
List<ServerPlugin> pluginsToDisable = new ArrayList<ServerPlugin>();
for (ServerPlugin selectedPlugin : allSelectedPlugins) {
if (selectedPlugin.isEnabled()) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
pluginsToDisable.add(selectedPlugin);
}
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No enabled plugins were selected. Nothing to disable");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
serverPluginsBean.disableServerPlugins(subject, getIds(pluginsToDisable));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Disabled server plugins: "
+ selectedPluginNames);
} catch (Exception e) {
processException("Failed to disable server plugins", e);
}
return;
}
public void undeployServerPlugins() {
List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
List<ServerPlugin> pluginsToUndeploy = new ArrayList<ServerPlugin>();
for (ServerPlugin selectedPlugin : allSelectedPlugins) {
if (selectedPlugin.getStatus() == PluginStatusType.INSTALLED) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
pluginsToUndeploy.add(selectedPlugin);
}
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No deployed plugins were selected. Nothing to undeploy");
return;
}
try {
Subject subject = EnterpriseFacesContextUtility.getSubject();
serverPluginsBean.deleteServerPlugins(subject, getIds(pluginsToUndeploy));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Undeployed server plugins: "
+ selectedPluginNames);
} catch (Exception e) {
processException("Failed to undeploy server plugins", e);
}
return;
}
public void purgeServerPlugins() {
List<ServerPlugin> allSelectedPlugins = getSelectedServerPlugins();
List<String> selectedPluginNames = new ArrayList<String>();
for (ServerPlugin selectedPlugin : allSelectedPlugins) {
selectedPluginNames.add(selectedPlugin.getDisplayName());
}
if (selectedPluginNames.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "No plugins were selected. Nothing to purge");
return;
}
try {
//The JSF UI is no longer used for server plugins, so I'm just commenting out the code
//that would not compile anymore...
//Subject subject = EnterpriseFacesContextUtility.getSubject();
//serverPluginsBean.purgeServerPlugins(subject, getIds(allSelectedPlugins));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Purged server plugins: " + selectedPluginNames);
} catch (Exception e) {
processException("Failed to undeploy server plugins", e);
}
return;
}
public void purgeAgentPlugins() {
try {
List<Plugin> selectedPlugins = getSelectedAgentPlugins();
if (selectedPlugins.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO,
"No plugins were selected. Nothing to purge");
return;
}
List<String> pluginsToDelete = new ArrayList<String>();
for (Plugin plugin : selectedPlugins) {
if (plugin.getStatus() != PluginStatusType.DELETED) {
pluginsToDelete.add(plugin.getName());
}
}
if (!pluginsToDelete.isEmpty()) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN, "Plugins must be deleted before they " +
"they can be purged. The following plugins must first be deleted: " + pluginsToDelete + ". No " +
"plugins were purged.");
return;
}
List<String> pluginNames = new ArrayList<String>();
for (Plugin plugin : selectedPlugins) {
pluginNames.add(plugin.getName());
}
//Plugin deletion has been reimplemented to not require an explicit purge operation
//This UI bean is now not used, so I just comment out the conflicting pieces of impl.
//Subject subject = EnterpriseFacesContextUtility.getSubject();
//pluginMgr.markPluginsForPurge(subject, getIds(getSelectedAgentPlugins()));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Preparing to purge agent plugins: " +
pluginNames + ". This may take a few minutes since all type definitions from the plugins must " +
"first be purged from the system. The plugins will still be visible on this page until they have " +
"been purged. Please note that you must not re-install the plugin while the purge is running, " +
"as this is going to fail. Wait for re-add until the purge is done."
);
} catch (Exception e) {
processException("Failed to purge agent plugins", e);
}
}
private List<Integer> getIds(List<? extends AbstractPlugin> plugins) {
ArrayList<Integer> ids = new ArrayList<Integer>(plugins.size());
for (AbstractPlugin plugin : plugins) {
ids.add(plugin.getId());
}
return ids;
}
private List<Plugin> getSelectedAgentPlugins() {
Integer[] integerItems = getSelectedPluginIds();
List<Integer> ids = Arrays.asList(integerItems);
List<Plugin> plugins = pluginMgr.getAllPluginsById(ids);
return plugins;
}
private List<ServerPlugin> getSelectedServerPlugins() {
Integer[] integerItems = getSelectedPluginIds();
List<Integer> ids = Arrays.asList(integerItems);
List<ServerPlugin> plugins = serverPluginsBean.getAllServerPluginsById(ids);
return plugins;
}
private Integer[] getSelectedPluginIds() {
String[] stringItems = FacesContextUtility.getRequest().getParameterValues("selectedPlugin");
if (stringItems == null || stringItems.length == 0) {
return new Integer[0];
}
Integer[] integerItems = StringUtility.getIntegerArray(stringItems);
return integerItems;
}
/**
* Throws a permission exception if the user is not allowed to access this functionality.
*/
private void hasPermission() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
if (!LookupUtil.getAuthorizationManager().hasGlobalPermission(subject, Permission.MANAGE_SETTINGS)) {
throw new PermissionException("User [" + subject.getName()
+ "] does not have the proper permissions to view or manage plugins");
}
}
private void processException(String errMsg, Exception e) {
log.error(errMsg + ". Cause: " + ThrowableUtil.getAllMessages(e));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, errMsg, e);
}
private <T extends AbstractPlugin> List<T> sort(List<T> plugins) {
TreeMap<String, T> map = new TreeMap<String, T>();
for (T plugin : plugins) {
map.put(plugin.getName(), plugin);
}
return new ArrayList<T>(map.values());
}
}