/* * 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.core.pc.configuration; import static org.rhq.core.domain.configuration.ConfigurationUpdateStatus.*; import java.util.List; import java.util.concurrent.Callable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest; import org.rhq.core.clientapi.server.configuration.ConfigurationServerService; import org.rhq.core.clientapi.server.configuration.ConfigurationUpdateResponse; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; /** * Performs the actual configuration of a resource by invoking the configuration facet of a resource component. * * @author Mark Spritzler */ public class UpdateResourceConfigurationRunner implements Runnable, Callable<ConfigurationUpdateResponse> { private final Log log = LogFactory.getLog(UpdateResourceConfigurationRunner.class); /** * request that was used to trigger this update. */ private ConfigurationUpdateRequest request; private ConfigManagement configMgmt; /** * The resource component's facet that will perform the actual re-configuration of the resource. */ private ConfigurationFacet configurationFacet; /** * The type of resource that is being reconfigured. */ private ResourceType resourceType; /** * The object to be notified when the configuration is done. May be <code>null</code> if there is no external server * service to be notified. */ private ConfigurationServerService configurationServerService; private ConfigurationUtilityService configUtilService = new ConfigurationUtilityServiceImpl(); public UpdateResourceConfigurationRunner(ConfigurationServerService configurationServerService, ResourceType type, ConfigManagement configMgmt, ConfigurationUpdateRequest request) { this.configurationServerService = configurationServerService; // may be null this.resourceType = type; this.configMgmt = configMgmt; this.request = request; } ConfigurationUpdateRequest getRequest() { return request; } ConfigManagement getConfigMgmt() { return configMgmt; } ResourceType getResourceType() { return resourceType; } ConfigurationServerService getConfigurationServerService() { return configurationServerService; } ConfigurationUtilityService getConfigUtilService() { return configUtilService; } void setConfigUtilService(ConfigurationUtilityService service) { configUtilService = service; } public void run() { try { call(); } catch (Exception e) { log.error("Error while chaining run to call", e); } } public ConfigurationUpdateResponse call() throws Exception { ConfigurationUpdateResponse response; int requestId = request.getConfigurationUpdateId(); try { response = new ConfigurationUpdateResponse(requestId, request.getConfiguration(), SUCCESS, null); try { configMgmt.executeUpdate(request.getResourceId(), request.getConfiguration()); } catch (UpdateInProgressException e) { response.setStatus(INPROGRESS); response.setErrorMessage("Configuration facet did not indicate success or failure - assuming failure."); } catch (ConfigurationUpdateException e) { response.setStatus(FAILURE); response.setErrorMessage(e.getMessage()); } ConfigurationDefinition configurationDefinition = resourceType.getResourceConfigurationDefinition(); // Normalize and validate the config. configUtilService.normalizeConfiguration(response.getConfiguration(), configurationDefinition); List<String> errorMessages = configUtilService.validateConfiguration(response.getConfiguration(), configurationDefinition); for (String errorMessage : errorMessages) { log.warn("Plugin Error: Invalid " + resourceType.getName() + " Resource configuration returned by " + resourceType.getPlugin() + " plugin - " + errorMessage); } // If it was successful, there is no need to waste bandwidth and send back the entire configuration again. // Just set it to null - the remote client will see it was a success and assume the configuration that was // saved is the same configuration that was passed in via the request. if (response.getStatus() == ConfigurationUpdateStatus.SUCCESS) { response.setConfiguration(null); } } catch (Throwable t) { log.error("Plugin Error: Exception thrown while updating Resource configuration for " + resourceType.getName() + " Resource with id [" + request.getResourceId() + "].", t); response = new ConfigurationUpdateResponse(requestId, request.getConfiguration(), t); } if (this.configurationServerService != null) { this.configurationServerService.completeConfigurationUpdate(response); } return response; } }