/*
* NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2004-2008], Hyperic, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.hyperic.hq.appdef.server.session;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.ObjectNotFoundException;
import org.hyperic.hq.appdef.shared.AppdefEntityConstants;
import org.hyperic.hq.appdef.shared.AppdefEntityID;
import org.hyperic.hq.appdef.shared.AppdefEntityNotFoundException;
import org.hyperic.hq.appdef.shared.AppdefEntityValue;
import org.hyperic.hq.appdef.shared.AppdefResourceTypeValue;
import org.hyperic.hq.appdef.shared.CPropChangeEvent;
import org.hyperic.hq.appdef.shared.CPropKeyExistsException;
import org.hyperic.hq.appdef.shared.CPropKeyNotFoundException;
import org.hyperic.hq.appdef.shared.CPropManager;
import org.hyperic.hq.appdef.shared.ServerNotFoundException;
import org.hyperic.hq.appdef.shared.ServiceNotFoundException;
import org.hyperic.hq.authz.shared.PermissionException;
import org.hyperic.hq.common.SystemException;
import org.hyperic.hq.common.util.Messenger;
import org.hyperic.hq.events.EventConstants;
import org.hyperic.hq.product.TypeInfo;
import org.hyperic.util.config.ConfigResponse;
import org.hyperic.util.config.EncodingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@SuppressWarnings("restriction")
@Service
@Transactional
public class CPropManagerImpl implements CPropManager {
private static Log log = LogFactory.getLog(CPropManagerImpl.class.getName());
private Messenger sender;
private CpropDAO cPropDAO;
private CpropKeyDAO cPropKeyDAO;
private ApplicationTypeDAO applicationTypeDAO;
private PlatformTypeDAO platformTypeDAO;
private ServerTypeDAO serverTypeDAO;
private ServiceTypeDAO serviceTypeDAO;
@Autowired
public CPropManagerImpl(Messenger sender, CpropDAO cPropDAO, CpropKeyDAO cPropKeyDAO,
ApplicationTypeDAO applicationTypeDAO, PlatformTypeDAO platformTypeDAO,
ServerTypeDAO serverTypeDAO, ServiceTypeDAO serviceTypeDAO) {
this.sender = sender;
this.cPropDAO = cPropDAO;
this.cPropKeyDAO = cPropKeyDAO;
this.applicationTypeDAO = applicationTypeDAO;
this.platformTypeDAO = platformTypeDAO;
this.serverTypeDAO = serverTypeDAO;
this.serviceTypeDAO = serviceTypeDAO;
}
// @PostConstruct
// public void afterPropertiesSet() throws Exception {
// this.vmMgr = (VCManager) Bootstrap.getBean("VMManagerImpl");
// }
/**
* Get all the keys associated with an appdef resource type.
*
* @param appdefType One of AppdefEntityConstants.APPDEF_TYPE_*
* @param appdefTypeId The ID of the appdef resource type
*
* @return a List of CPropKeyValue objects
*/
@Transactional(readOnly = true)
public List<CpropKey> getKeys(int appdefType, int appdefTypeId) {
return cPropKeyDAO.findByAppdefType(appdefType, appdefTypeId);
}
private AppdefResourceType findResourceType(int appdefType, int appdefTypeId)
throws AppdefEntityNotFoundException {
Integer id = new Integer(appdefTypeId);
if (appdefType == AppdefEntityConstants.APPDEF_TYPE_PLATFORM) {
return platformTypeDAO.findById(id);
} else if (appdefType == AppdefEntityConstants.APPDEF_TYPE_SERVER) {
try {
return serverTypeDAO.findById(id);
} catch (ObjectNotFoundException exc) {
throw new ServerNotFoundException("Server type id=" + appdefTypeId + " not found");
}
} else if (appdefType == AppdefEntityConstants.APPDEF_TYPE_SERVICE) {
try {
return serviceTypeDAO.findById(id);
} catch (ObjectNotFoundException exc) {
throw new ServiceNotFoundException("Service type id=" + appdefTypeId + " not found");
}
} else if (appdefType == AppdefEntityConstants.APPDEF_TYPE_APPLICATION) {
return applicationTypeDAO.findById(id);
} else {
throw new IllegalArgumentException("Unrecognized appdef type:" + " " + appdefType);
}
}
/**
* find appdef resource type
*/
@Transactional(readOnly = true)
public AppdefResourceType findResourceType(TypeInfo info) {
int type = info.getType();
if (type == AppdefEntityConstants.APPDEF_TYPE_PLATFORM) {
return platformTypeDAO.findByName(info.getName());
} else if (type == AppdefEntityConstants.APPDEF_TYPE_SERVER) {
return serverTypeDAO.findByName(info.getName());
} else if (type == AppdefEntityConstants.APPDEF_TYPE_SERVICE) {
return serviceTypeDAO.findByName(info.getName());
} else {
throw new IllegalArgumentException("Unrecognized appdef type: " + info);
}
}
/**
* @return {@link Map} of {@link String} to {@link AppdefResourceType}s
*/
@Transactional(readOnly = true)
public Map<String, AppdefResourceType> findResourceType(Collection<TypeInfo> typeInfos) {
List<String> platformTypeInfos = new ArrayList<String>();
List<String> serverTypeInfos = new ArrayList<String>();
List<String> serviceTypeInfos = new ArrayList<String>();
for (final TypeInfo info : typeInfos) {
int type = info.getType();
if (type == AppdefEntityConstants.APPDEF_TYPE_PLATFORM) {
platformTypeInfos.add(info.getName());
} else if (type == AppdefEntityConstants.APPDEF_TYPE_SERVER) {
serverTypeInfos.add(info.getName());
} else if (type == AppdefEntityConstants.APPDEF_TYPE_SERVICE) {
serviceTypeInfos.add(info.getName());
} else {
throw new IllegalArgumentException("Unrecognized appdef type: " + info);
}
}
List<AppdefResourceType> resTypes = new ArrayList<AppdefResourceType>(typeInfos.size());
Map<String, AppdefResourceType> rtn = new HashMap<String, AppdefResourceType>(typeInfos
.size());
if (platformTypeInfos.size() > 0) {
resTypes.addAll(platformTypeDAO.findByName(platformTypeInfos));
}
if (serverTypeInfos.size() > 0) {
resTypes.addAll(serverTypeDAO.findByName(serverTypeInfos));
}
if (serviceTypeInfos.size() > 0) {
resTypes.addAll(serviceTypeDAO.findByName(serviceTypeInfos));
}
for (AppdefResourceType type : resTypes) {
rtn.put(type.getName(), type);
}
return rtn;
}
/**
* find Cprop by key to a resource type based on a TypeInfo object.
*/
@Transactional(readOnly = true)
public CpropKey findByKey(AppdefResourceType appdefType, String key) {
int type = appdefType.getAppdefType();
int instanceId = appdefType.getId().intValue();
return cPropKeyDAO.findByKey(type, instanceId, key);
}
/**
* Add a key to a resource type based on a TypeInfo object.
*
* @throw AppdefEntityNotFoundException if the appdef resource type that the
* key references could not be found
* @throw CPropKeyExistsException if the key already exists
*/
public void addKey(AppdefResourceType appdefType, String key, String description) {
int type = appdefType.getAppdefType();
int instanceId = appdefType.getId().intValue();
cPropKeyDAO.create(type, instanceId, key, description);
}
/**
* Add a key to a resource type. The key's 'appdefType' and 'appdefTypeId'
* fields are used to locate the resource -- if that resource does not
* exist, an AppdefEntityNotFoundException will be thrown.
*
* @param key Key to create
* @throw AppdefEntityNotFoundException if the appdef resource type that the
* key references could not be found
* @throw CPropKeyExistsException if the key already exists
*/
public void addKey(CpropKey key) throws AppdefEntityNotFoundException, CPropKeyExistsException {
// Insure that the resource type exists
AppdefResourceType recValue = findResourceType(key.getAppdefType(), key.getAppdefTypeId());
CpropKey cpKey = cPropKeyDAO.findByKey(key.getAppdefType(), key.getAppdefTypeId(), key
.getKey());
if (cpKey != null) {
throw new CPropKeyExistsException("Key, '" +
key.getKey() +
"', " +
"already exists for " +
AppdefEntityConstants.typeToString(recValue
.getAppdefType()) + " type, '" +
recValue.getName() + "'");
}
cPropKeyDAO.create(key.getAppdefType(), key.getAppdefTypeId(), key.getKey(), key
.getDescription());
}
/**
* Remove a key from a resource type.
*
* @param appdefType One of AppdefEntityConstants.APPDEF_TYPE_*
* @param appdefTypeId The ID of the resource type
* @param key Key to remove
*
* @throw CPropKeyNotFoundException if the CPropKey could not be found
*/
public void deleteKey(int appdefType, int appdefTypeId, String key)
throws CPropKeyNotFoundException {
CpropKey cpKey = cPropKeyDAO.findByKey(appdefType, appdefTypeId, key);
if (cpKey == null) {
throw new CPropKeyNotFoundException("Key, '" + key + "', does not" + " exist for " +
AppdefEntityConstants.typeToString(appdefType) +
" " + appdefTypeId);
}
// cascade on delete to remove Cprop as well
cPropKeyDAO.remove(cpKey);
}
/**
* Set (or delete) a custom property for a resource. If the property already
* exists, it will be overwritten.
*
* @param aID Appdef entity id to set the value for
* @param typeId Resource type id
* @param key Key to associate the value with
* @param val Value to assicate with the key. If the value is null, then the
* value will simply be removed.
*
* @throw CPropKeyNotFoundException if the key has not been created for the
* resource's associated type
* @throw AppdefEntityNotFoundException if id for 'aVal' specifies a
* resource which does not exist
*/
public void setValue(AppdefEntityID aID, int typeId, String key, String val)
throws CPropKeyNotFoundException, AppdefEntityNotFoundException, PermissionException {
String oldval;
try {
oldval = cPropDAO.setValue(aID, typeId, key, val);
}catch(Exception e) {
log.error("Unable to update CPropKey values: " + e.getMessage(), e);
throw new SystemException(e);
}
if((val == null && oldval == null) || (val != null && val.equals(oldval))) {
//We didn't change anything
return;
}
if (log.isDebugEnabled()) {
log.debug("Entity " + aID.getAppdefKey() + " " + key + " changed from " + oldval +
" to " + val);
}
// Send cprop value changed event
CPropChangeEvent event = new CPropChangeEvent(aID, key, oldval, val);
sender.publishMessage(EventConstants.EVENTS_TOPIC, event);
}
/**
* Get a custom property for a resource.
*
* @param aVal Appdef entity to get the value for
* @param key Key of the value to get
*
* @return The value associated with 'key' if found, else null
*
* @throw CPropKeyNotFoundException if the key for the associated resource
* is not found
* @throw AppdefEntityNotFoundException if the passed entity is not found
*/
@Transactional(readOnly = true)
public String getValue(AppdefEntityValue aVal, String key) throws CPropKeyNotFoundException,
AppdefEntityNotFoundException, PermissionException {
try {
return cPropDAO.getValue(aVal, key);
}catch(Exception e) {
log.error("Unable to get CPropKey values: " + e.getMessage(), e);
throw new SystemException(e);
}
}
/**
* Get a map which holds the keys & their associated values for an appdef
* entity.
*
* @param aID Appdef entity id to get the custom properties for
*
* @return The properties stored for a specific entity ID. An empty
* Properties object will be returned if there are no custom
* properties defined for the resource
*/
@Transactional(readOnly = true)
public Properties getEntries(AppdefEntityID aID) throws PermissionException,
AppdefEntityNotFoundException {
return cPropDAO.getEntries(aID, "propkey");
}
@Transactional(readOnly = true)
public Map<AppdefEntityID, Properties> getAllEntries(String ... keys) {
return cPropDAO.getAllEntries(keys);
}
/**
* Get a map which holds the descriptions & their associated values for an
* appdef entity.
*
* @param aID Appdef entity id to get the custom properties for
*
* @return The properties stored for a specific entity ID
*/
@Transactional(readOnly = true)
public Properties getDescEntries(AppdefEntityID aID) throws PermissionException,
AppdefEntityNotFoundException {
return cPropDAO.getEntries(aID, "description");
}
/**
* Set custom properties for a resource. If the property already exists, it
* will be overwritten.
*
* @param aID Appdef entity id to set the value for
* @param typeId Resource type id
* @param data Encoded ConfigResponse
*/
public void setConfigResponse(AppdefEntityID aID, int typeId, byte[] data)
throws PermissionException, AppdefEntityNotFoundException {
if (data == null) {
return;
}
ConfigResponse cprops;
try {
cprops = ConfigResponse.decode(data);
} catch (EncodingException e) {
throw new SystemException(e);
}
if (log.isDebugEnabled()) {
log.debug("cprops=" + cprops);
log.debug("aID=" + aID.toString() + ", typeId=" + typeId);
}
for (Iterator<String> it = cprops.getKeys().iterator(); it.hasNext();) {
String key = it.next();
String val = cprops.getValue(key);
try {
setValue(aID, typeId, key, val);
} catch (CPropKeyNotFoundException e) {
log.error(e.getMessage(), e);
}
}
}
/**
* Remove custom properties for a given resource.
*/
public void deleteValues(int appdefType, int id) {
try {
cPropDAO.deleteValues(appdefType, id);
}catch(Exception e) {
log.error("Unable to delete CProp values: " + e.getMessage(), e);
throw new SystemException(e);
}
}
/**
* Get all Cprops values with specified key name, regardless of type
*/
@Transactional(readOnly = true)
public List<Cprop> getCPropValues(AppdefResourceTypeValue appdefType, String key, boolean asc) {
int type = appdefType.getAppdefType();
int instanceId = appdefType.getId().intValue();
CpropKey pkey = cPropKeyDAO.findByKey(type, instanceId, key);
return cPropDAO.findByKeyName(pkey, asc);
}
}