/*
* NOTE: This copyright does *not* cover user programs that use Hyperic
* 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-2012], VMware, Inc.
* This file is part of Hyperic.
*
* Hyperic 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.api.transfer.impl;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.ws.rs.core.Response;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperic.hq.agent.AgentConnectionException;
import org.hyperic.hq.api.model.ConfigurationTemplate;
import org.hyperic.hq.api.model.ConfigurationValue;
import org.hyperic.hq.api.model.MetricTemplate;
import org.hyperic.hq.api.model.PropertyList;
import org.hyperic.hq.api.model.ResourceConfig;
import org.hyperic.hq.api.model.ResourceDetailsType;
import org.hyperic.hq.api.model.ResourceModel;
import org.hyperic.hq.api.model.ResourceStatusType;
import org.hyperic.hq.api.model.ResourceTypeModel;
import org.hyperic.hq.api.model.Resources;
import org.hyperic.hq.api.model.common.ExternalRegistrationStatus;
import org.hyperic.hq.api.model.common.RegistrationID;
import org.hyperic.hq.api.model.measurements.HttpEndpointDefinition;
import org.hyperic.hq.api.model.resources.ComplexIp;
import org.hyperic.hq.api.model.resources.RegisteredResourceBatchResponse;
import org.hyperic.hq.api.model.resources.ResourceBatchResponse;
import org.hyperic.hq.api.model.resources.ResourceFilterRequest;
import org.hyperic.hq.api.services.impl.ApiMessageContext;
import org.hyperic.hq.api.transfer.NotificationsTransfer;
import org.hyperic.hq.api.transfer.ResourceTransfer;
import org.hyperic.hq.api.transfer.mapping.ConfigurationTemplateMapper;
import org.hyperic.hq.api.transfer.mapping.ExceptionToErrorCodeMapper;
import org.hyperic.hq.api.transfer.mapping.MetricTemplateMapper;
import org.hyperic.hq.api.transfer.mapping.ResourceDetailsTypeStrategy;
import org.hyperic.hq.api.transfer.mapping.ResourceMapper;
import org.hyperic.hq.api.transfer.mapping.UnknownEndpointException;
import org.hyperic.hq.appdef.Ip;
import org.hyperic.hq.appdef.server.session.AppdefResource;
import org.hyperic.hq.appdef.server.session.Platform;
import org.hyperic.hq.appdef.server.session.Server;
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.AppdefResourceValue;
import org.hyperic.hq.appdef.shared.AppdefUtil;
import org.hyperic.hq.appdef.shared.CPropManager;
import org.hyperic.hq.appdef.shared.ConfigFetchException;
import org.hyperic.hq.appdef.shared.ConfigManager;
import org.hyperic.hq.appdef.shared.InvalidConfigException;
import org.hyperic.hq.appdef.shared.IpManager;
import org.hyperic.hq.appdef.shared.PlatformManager;
import org.hyperic.hq.appdef.shared.PlatformNotFoundException;
import org.hyperic.hq.appdef.shared.PlatformValue;
import org.hyperic.hq.appdef.shared.Property;
import org.hyperic.hq.appdef.shared.ServerValue;
import org.hyperic.hq.appdef.shared.ServiceValue;
import org.hyperic.hq.auth.shared.SessionNotFoundException;
import org.hyperic.hq.auth.shared.SessionTimeoutException;
import org.hyperic.hq.authz.server.session.AuthzSubject;
import org.hyperic.hq.authz.server.session.Resource;
import org.hyperic.hq.authz.shared.AuthzConstants;
import org.hyperic.hq.authz.shared.PermissionException;
import org.hyperic.hq.authz.shared.PermissionManager;
import org.hyperic.hq.authz.shared.PermissionManagerFactory;
import org.hyperic.hq.authz.shared.ResourceManager;
import org.hyperic.hq.autoinventory.AutoinventoryException;
import org.hyperic.hq.bizapp.server.session.ProductBossImpl.ConfigSchemaAndBaseResponse;
import org.hyperic.hq.bizapp.shared.AllConfigResponses;
import org.hyperic.hq.bizapp.shared.AppdefBoss;
import org.hyperic.hq.bizapp.shared.ProductBoss;
import org.hyperic.hq.common.ApplicationException;
import org.hyperic.hq.common.NotFoundException;
import org.hyperic.hq.common.ObjectNotFoundException;
import org.hyperic.hq.common.shared.HQConstants;
import org.hyperic.hq.context.Bootstrap;
import org.hyperic.hq.measurement.server.session.MeasurementTemplate;
import org.hyperic.hq.measurement.shared.MeasurementManager;
import org.hyperic.hq.notifications.DefaultEndpoint;
import org.hyperic.hq.notifications.HttpEndpoint;
import org.hyperic.hq.notifications.NotificationEndpoint;
import org.hyperic.hq.notifications.filtering.Filter;
import org.hyperic.hq.notifications.filtering.FilterChain;
import org.hyperic.hq.notifications.filtering.FilteringCondition;
import org.hyperic.hq.notifications.filtering.ResourceDestinationEvaluator;
import org.hyperic.hq.notifications.model.InventoryNotification;
import org.hyperic.hq.product.PluginException;
import org.hyperic.hq.product.PluginNotFoundException;
import org.hyperic.hq.product.ProductPlugin;
import org.hyperic.hq.product.shared.ProductManager;
import org.hyperic.hq.scheduler.ScheduleWillNeverFireException;
import org.hyperic.util.Transformer;
import org.hyperic.util.config.ConfigResponse;
import org.hyperic.util.config.ConfigSchema;
import org.hyperic.util.config.EncodingException;
import org.hyperic.util.timer.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.transaction.annotation.Transactional;
public class ResourceTransferImpl implements ResourceTransfer {
private static final Log log = LogFactory.getLog(ResourceTransferImpl.class);
private static final String IP_MAC_ADDRESS_KEY = "IP_MAC_ADDRESS" ;
private ResourceManager resourceManager ;
private ResourceMapper resourceMapper;
private ProductBoss productBoss ;
private CPropManager cpropManager ;
private AppdefBoss appdepBoss ;
private PlatformManager platformManager ;
private ExceptionToErrorCodeMapper errorHandler ;
private ResourceDestinationEvaluator evaluator;
private ConfigManager configManager;
private IpManager ipManager;
protected NotificationsTransfer notificationsTransfer;
protected ProductManager productManager;
protected MeasurementManager measurementManager;
protected ConfigurationTemplateMapper configTemplateMapper;
@Autowired
protected MetricTemplateMapper metricTemplateMapper;
protected PermissionManager permissionManager;
@Autowired
public ResourceTransferImpl(ResourceManager resourceManager, ResourceMapper resourceMapper,
ProductBoss productBoss, CPropManager cpropManager, AppdefBoss appdepBoss,
PlatformManager platformManager, final ConfigurationTemplateMapper configTemplateMapper, ExceptionToErrorCodeMapper errorHandler,
ResourceDestinationEvaluator evaluator, ConfigManager configManager,
IpManager ipManager, ProductManager productManager, MeasurementManager measurementManager) {
this.resourceManager = resourceManager ;
this.resourceMapper = resourceMapper ;
this.productBoss = productBoss ;
this.cpropManager = cpropManager ;
this.appdepBoss = appdepBoss ;
this.platformManager = platformManager ;
this.configTemplateMapper = configTemplateMapper;
this.errorHandler = errorHandler ;
this.evaluator = evaluator;
this.configManager = configManager;
this.ipManager = ipManager;
this.productManager = productManager;
this.measurementManager = measurementManager;
this.permissionManager = PermissionManagerFactory.getInstance();
}//EOM
@PostConstruct
public void init() {
this.notificationsTransfer = (NotificationsTransfer) Bootstrap.getBean("notificationsTransfer");
}
public final ResourceModel getResource(ApiMessageContext messageContext, final String platformNaturalID, final ResourceTypeModel resourceType,
final ResourceStatusType resourceStatusType, final int hierarchyDepth, final ResourceDetailsType[] responseMetadata) throws SessionNotFoundException, SessionTimeoutException, ObjectNotFoundException {
AuthzSubject authzSubject = messageContext.getAuthzSubject();
if(resourceStatusType == ResourceStatusType.AUTO_DISCOVERED) {
return this.getAIResource(platformNaturalID, resourceType, hierarchyDepth, responseMetadata) ;
}else {
return this.getResourceInner(new Context(authzSubject, platformNaturalID, resourceType, responseMetadata, this), hierarchyDepth) ;
}//EO else if approved resource
}//EOM
/**
* Note: AI resources are unsupported
* @param platformID
* @param resourceStatusType
* @param hierarchyDepth
* @param responseMetadata
* @return
* @throws ObjectNotFoundException
*/
public final ResourceModel getResource(ApiMessageContext messageContext, final String platformID, final ResourceStatusType resourceStatusType, final int hierarchyDepth, final ResourceDetailsType[] responseMetadata) throws ObjectNotFoundException {
AuthzSubject authzSubject = messageContext.getAuthzSubject();
if(resourceStatusType == ResourceStatusType.AUTO_DISCOVERED) {
throw new UnsupportedOperationException("AI Resource load by internal ID is unsupported") ;
}else {
return this.getResourceInner(new Context(authzSubject, platformID, responseMetadata, this), hierarchyDepth) ;
}//EO else if approved resource type
}//EOM
/**
* @param hierarchyDepth
* @return
* @throws ObjectNotFoundException
*/
private final ResourceModel getResourceInner(final Context flowContext, int hierarchyDepth) throws ObjectNotFoundException {
ResourceModel currentResource = null ;
try{
//derive the resource type load strategy using the resource type enum
//Note: of the resourceType is null, then the generic resource resource type
//would be used
final ResourceTypeStrategy resourceTypeStrategy = ResourceTypeStrategy.valueOf(flowContext.resourceType) ;
//if the resource Type is null then find by internal id else natural id
flowContext.setBackendResource(resourceTypeStrategy.getResource(flowContext)) ;
//populate the response resource (excluding the children)
for(ResourceDetailsTypeStrategy resourceDetailType : flowContext.resourceDetails) {
resourceDetailType.populateResource(flowContext) ;
}//EO while there are more resource details
//if resource root was not yet initialized do so now
//if(flowContext.resourceRoot == null) flowContext.resourceRoot = flowContext.currResource ;
currentResource = flowContext.currResource ;
//starts from 1
if(--hierarchyDepth > 0) {
//populate the resource's children
final List<Resource> listBackendResourceChildren =
this.resourceManager.findChildren(flowContext.subject, flowContext.backendResource) ;
ResourceModel resourceChild = null ;
for(Resource backendResourceChild : listBackendResourceChildren) {
flowContext.reset() ;
//set the child in the flow's backend resource
flowContext.setBackendResource(backendResourceChild) ;
flowContext.resourceType = ResourceTypeModel.valueOf(backendResourceChild.getResourceType().getAppdefType()) ;
resourceChild = this.getResourceInner(flowContext, hierarchyDepth) ;
currentResource.addSubResource(resourceChild) ;
}//EO while there are more children
}//EOM
} catch (ObjectNotFoundException e) {
throw e;
}catch(Throwable t) {
throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t)) ;
}//EO catch block
return currentResource ;
}//EOM
public final ResourceBatchResponse approveResource(ApiMessageContext messageContext, final Resources aiResources) {
//NYI
return null;
}//EOM
@Transactional(readOnly=false)
public final ResourceBatchResponse updateResources(ApiMessageContext messageContext, final Resources resources) {
final ResourceBatchResponse response = new ResourceBatchResponse(this.errorHandler) ;
//iterate over the resources and for each resource, update the following metadata if exists and changed:
//TODO: if no resources where provided (null or empty) should an excpetion be thrown?
final List<ResourceModel> resourcesList = resources.getResources() ;
if(resourcesList == null) return response ;
String resourceID = null ;
final int noOfInputResources = resourcesList.size() ;
ResourceModel inputResource = null ;
ResourceConfig resourceConfig = null ;
AuthzSubject authzSubject = messageContext.getAuthzSubject();
final Context flowContext = new Context(authzSubject, this) ;
int failureCounter = 0 ;
for(int i=0; i < noOfInputResources; i++) {
try{
inputResource = resourcesList.get(i) ;
flowContext.setInputResource(inputResource) ;
//find the backend resource using the resource Type (if null then find by internal id else natural id)
//not need to check for null backendResource as exception should have been thrown if the resource
//could not have been loaded
final ResourceTypeStrategy resourceTypeStrategy = ResourceTypeStrategy.valueOf(inputResource.getResourceType()) ;
flowContext.setBackendResource(resourceTypeStrategy.getResource(flowContext)) ;
flowContext.resourceTypeStrategy = resourceTypeStrategy ;
//map the input into the backend resource (resource metadata update
this.resourceMapper.mergeResource(inputResource, flowContext.backendResource, flowContext) ;
//if there are properties to update do so now
resourceConfig = inputResource.getResourceConfig() ;
if(resourceConfig != null && resourceConfig.getMapProps() != null) this.updateResourceConfig(flowContext, resourceConfig) ;
}catch(Throwable t) {
this.errorHandler.log(t) ;
resourceID = ResourceTypeStrategy.getResourceIdentifier(flowContext.currResource) ;
String description = resourceID, additionalDescription = null ;
if(t instanceof NumberFormatException) {
description = "Resource ID " + resourceID ;
}//EO if number format
else if(t instanceof InvalidConfigException) {
additionalDescription = t.getMessage() ;
}//EO else if InvalidConfigException
response.addFailedResource(t,resourceID, additionalDescription /*additional Description*/, description) ;
resourceID = null ;
failureCounter++ ;
} finally { //EO catch block
flowContext.reset() ;
}//EO catch block
}//EO while there are more resources
//if the failure counter == no of input resources, raise an error rather than returning success with failed resources section
if(failureCounter == noOfInputResources) {
throw this.errorHandler.newWebApplicationException(new Throwable(), Response.Status.INTERNAL_SERVER_ERROR,
ExceptionToErrorCodeMapper.ErrorCode.UPDATE_FAILURE, ". Failed to update all " + noOfInputResources + " input resources.");
}//EO if overall update failuer
return response ;
}//EOM
/**
*
* Note: AI resource updates are unsupported
* Note: Currently all-or-nothing.
*
* @param flowContext
* @param resourceConfig
* @throws EncodingException
* @throws PluginNotFoundException
* @throws PluginException
* @throws ScheduleWillNeverFireException
* @throws ApplicationException
* @throws AutoinventoryException
* @throws AgentConnectionException
*/
private final void updateResourceConfig(final Context flowContext, final ResourceConfig resourceConfig) throws
EncodingException, PluginNotFoundException, PluginException, ScheduleWillNeverFireException, ApplicationException, AutoinventoryException, AgentConnectionException {
final Resource resource = flowContext.backendResource ;
final AppdefEntityID entityID = flowContext.entityID = AppdefUtil.newAppdefEntityId(resource) ;
//load existing resource config data
this.initResourceConfig(flowContext) ;
//merge cprops
final Resource prototype = resource.getPrototype() ;
final int appdefTypeID = resource.getResourceType().getAppdefType() ;
Object oldValue = null ;
String sKey = null, sNewValue = null ;
//iterate over the new config properties and search for a match in the following config sub systems
// - cprops
// - config response
//if not found in the above, store the value so that a user response may contain a list of unset (new) properties
final Map<String,String> configValues = resourceConfig.getMapProps() ;
final List<String> listUnmatchedConfigProperties = new ArrayList<String>(configValues.size());
//config resource modifications
final AllConfigResponses allConfigs = new AllConfigResponses(), rollbackConfigs = new AllConfigResponses() ;
rollbackConfigs.setResource(allConfigs.setResource(entityID)) ;
final int iNoOfConfigurableTypes = ProductPlugin.CONFIGURABLE_TYPES.length ;
final ConfigResponse[] newConfigResponses = new ConfigResponse[iNoOfConfigurableTypes] ;
ConfigSchemaAndBaseResponse configResponse = null ;
ConfigSchema configSchema = null ;
ConfigResponse currConfigData = null, newConfigData = null ;
boolean bKeySupported = false, bOverallKeySupported = false, bHadConfigResponsesChanged = false ;
for(Map.Entry<String,String> entry : configValues.entrySet()) {
sKey = entry.getKey() ;
sNewValue = entry.getValue() ;
if(flowContext.cprops != null) {
oldValue = flowContext.cprops.get(sKey) ;
if((bKeySupported = flowContext.cprops.containsKey(sKey)) && (oldValue == null || !oldValue.equals(sNewValue))) {
this.cpropManager.setValue(entityID, appdefTypeID, sKey, sNewValue) ;
}//EO if the property exists and the value is different
}//EO if there were cprops associated with the resource
for(int i=0; i < iNoOfConfigurableTypes; i++) {
configResponse = flowContext.configResponses[i] ;
if(configResponse == null) {
rollbackConfigs.setSupports(i, false) ;
}else {
allConfigs.setSupports(i, true) ;
rollbackConfigs.setSupports(i, true) ;
rollbackConfigs.setConfig(i, configResponse.getResponse()) ;
newConfigData = newConfigResponses[i] ;
if(newConfigData == null) {
newConfigData = newConfigResponses[i] = new ConfigResponse() ;
allConfigs.setConfig(i, newConfigData) ;
}//EO if not yet initialized
currConfigData = configResponse.getResponse() ;
oldValue = currConfigData.getValue(sKey) ;
//if the current configResponse contains the key and the value is different,
//override with the new value else ignore
if( (bKeySupported = (oldValue != null || currConfigData.supportsOption(sKey))) && (oldValue == null || !oldValue.equals(sNewValue))) {
newConfigData.setValue(sKey, sNewValue) ;
bHadConfigResponsesChanged = true ;
allConfigs.setShouldConfig(i, true) ;
}//EO if the config option was provided and was different than the current
bOverallKeySupported = (bOverallKeySupported || bKeySupported) ;
}//EO else if config data was defined
}//EO while there are more config resources
//if !bConfigChanged then the key was not supported and should be discarded
if(!bOverallKeySupported) listUnmatchedConfigProperties.add(sKey) ;
//reset the overall key support flag
bOverallKeySupported = false ;
}//EO while there are more new entries
//only store the configResponse if modifications were made
if(bHadConfigResponsesChanged) {
//allConfigs.setEnableRuntimeAIScan(true) ;
//rollbackConfigs.setEnableRuntimeAIScan(true);
this.appdepBoss.setAllConfigResponses(flowContext.subject, allConfigs, rollbackConfigs, true) ;
}//EO if there was a change
//TODO: pojo fields modifications
}//EOM
public final void initResourceVirtualData(final Context flowContext)
throws ConfigFetchException, EncodingException, PluginNotFoundException, PluginException, PermissionException, AppdefEntityNotFoundException {
flowContext.cprops = cpropManager.getEntries(flowContext.entityID) ;
}
public final Object initResourceConfig(final Context flowContext)
throws ConfigFetchException, EncodingException, PluginNotFoundException, PluginException, PermissionException,
AppdefEntityNotFoundException {
final int iNoOfConfigTypes = ProductPlugin.CONFIGURABLE_TYPES.length ;
ConfigSchemaAndBaseResponse configMetadata = null ;
//load all resource related config metadata&data resources
String configurableType = null ;
for(int i=0; i < iNoOfConfigTypes; i++) {
configurableType = ProductPlugin.CONFIGURABLE_TYPES[i] ;
try {
flowContext.configResponses[i] = configMetadata = productBoss.getConfigSchemaAndBaseResponse(
flowContext.subject, flowContext.entityID, configurableType, false/*validateFlow*/) ;
//init the schema map in the config response so as to support key recognition validation
configMetadata.getResponse().setSchema(configMetadata.getSchema()) ;
}catch(PluginNotFoundException pnfe) {
log.debug("Plugin Config Schema of type: " + configurableType + " was not defined for resource " + flowContext.entityID) ;
}//EO catch block
// XXX why are we catching an NPE???
catch(NullPointerException npe) {
npe.printStackTrace() ;
}
}//EO while there are more configurable types
//load all cprop metadata
final Resource prototype = flowContext.backendResource.getPrototype() ;
flowContext.cprops = cpropManager.getEntries(flowContext.entityID) ;
//TODO: pojo members data
return null ;
}//EOM
public ConfigurationTemplate getConfigurationTemplate(ApiMessageContext apiMessageContext, String resourceID)
throws SessionTimeoutException, SessionNotFoundException, AppdefEntityNotFoundException,
ConfigFetchException, PermissionException {
final ResourceDetailsType[] detailsType = { ResourceDetailsType.BASIC };
final AuthzSubject authzSubject = apiMessageContext.getAuthzSubject();
final Integer sessionId = apiMessageContext.getSessionId();
final Resource resource = ResourceTypeStrategy.RESOURCE
.getResourceByInternalID(new Context(authzSubject, resourceID, detailsType, this));
final int numConfigTypes = ProductPlugin.CONFIGURABLE_TYPES.length;
ConfigurationTemplate configTemplate = null;
// load all prototype related config metadata
String configurableType = null;
for(int i = 0;i < numConfigTypes;i++) {
configurableType = ProductPlugin.CONFIGURABLE_TYPES[i];
try {
if(resourceIsPrototype(resource)) {
final String protototypeName = resource.getName();
final Map<String, ConfigSchema> configurations = this.productBoss.getConfigSchemas(protototypeName,
configurableType);
// Add to the existing configTemplate
configTemplate = this.configTemplateMapper.toConfigurationTemplate(configurations,
configurableType, configTemplate);
}else {// if resource is not a prototype
final AppdefEntityID entityID = AppdefUtil.newAppdefEntityId(resource);
try {
ConfigSchema config = this.productBoss.getConfigSchema(sessionId, entityID, configurableType);
// Add to the existing configTemplate
configTemplate = this.configTemplateMapper.toConfigurationTemplate(config, configurableType,
configTemplate);
} catch(EncodingException e) {
throw new ConfigFetchException(e, ProductPlugin.CONFIGURABLE_TYPES[i], entityID);
}
}// EO if resource is not a prototype
}catch(PluginException e) {
// not all plugins have all config types
log.debug("Plugin config not found for config type " + configurableType, e);
}
}// EO while there are more configTypes
return configTemplate;
}// EOM
public List<MetricTemplate> getMetricTemplates(ApiMessageContext apiMessageContext, String resourceID)
throws ObjectNotFoundException, SessionTimeoutException, SessionNotFoundException, PermissionException {
final ResourceDetailsType[] detailsType = { ResourceDetailsType.BASIC };
final AuthzSubject authzSubject = apiMessageContext.getAuthzSubject();
final Integer sessionId = apiMessageContext.getSessionId();
final Resource resource = ResourceTypeStrategy.RESOURCE
.getResourceByInternalID(new Context(authzSubject, resourceID, detailsType, this));
Collection<MeasurementTemplate> measurementTemplates;
if(resourceIsPrototype(resource)) {
measurementTemplates = measurementManager.getTemplatesByPrototype(resource);
} else {// if resource is not a prototype
throw new UnsupportedOperationException("Currently this operation is supported for resource prototypes only.");
}// EO if resource is not a prototype
List<MetricTemplate> metricTemplates = this.metricTemplateMapper.toMetricTemplates(resource, measurementTemplates);
return metricTemplates;
}// EOM
private boolean resourceIsPrototype(final org.hyperic.hq.authz.server.session.Resource resource) {
String name = resource.getResourceType().getName();
return AuthzConstants.platformPrototypeTypeName.equals(name) ||
AuthzConstants.serverPrototypeTypeName.equals(name) ||
AuthzConstants.servicePrototypeTypeName.equals(name);
}//EOM
public enum ResourceTypeStrategy {
PLATFORM(AppdefEntityConstants.APPDEF_TYPE_PLATFORM, PlatformValue.class) {
@Override
final Resource getResourceByNaturalID(final Context flowContext) throws PlatformNotFoundException, PermissionException {
final Platform platform = flowContext.visitor.getPlatformManager().findPlatformByFqdn(flowContext.subject, flowContext.naturalID);
flowContext.resourceInstance = platform ;
return platform.getResource() ;
}//EOM
@Override
protected final AppdefResourceValue loadExistingDTO(final AppdefBoss appdefBoss, final Context flowContext) throws Exception{
Platform platform = (Platform) flowContext.resourceInstance ;
if(platform == null) {
flowContext.resourceInstance = platform = flowContext.getVisitor().getPlatformManager().
findPlatformById(flowContext.backendResource.getInstanceId()) ;
}//EO else if platform was not yet loaded
final PlatformValue platformDTO = new PlatformValue() ;
platformDTO.setId(platform.getId()) ;
platformDTO.setFqdn(platform.getFqdn()) ;
platformDTO.setName(platform.getName()) ;
return platformDTO ;
}//EOM
@Override
protected final AppdefResourceValue mergeResource(final Map<String,String> inputProps, Map<String,PropertyList> oneToManyProps,
AppdefResourceValue existingDTO, final Context flowContext) throws Exception {
PropertyList requetsIps = null ;
if( (requetsIps = oneToManyProps.get(IP_MAC_ADDRESS_KEY)) != null) {
if(requetsIps != null) {
//else determine whether the ips have changed
Platform platform = (Platform) flowContext.resourceInstance ;
existingDTO = flowContext.visitor.getResourceMapper().mergePlatformIPs(existingDTO, requetsIps.getProperties(), platform) ;
}//EO if ips were provided
}//EO if propertyList was defined
return existingDTO ;
}//EOM
@Override
protected final void updateResourceInstance(final AppdefResourceValue newDTO,
final AppdefBoss appdefBoss, final AuthzSubject subject) throws Exception{
appdefBoss.updatePlatform(subject, (PlatformValue) newDTO) ;
}//EOM
},//EO PLATFORM
SERVER(AppdefEntityConstants.APPDEF_TYPE_SERVER, ServerValue.class) {
@Override
protected final AppdefResourceValue loadExistingDTO(final AppdefBoss appdefBoss, final Context flowContext) throws Exception {
AppdefResourceValue existingDTO = null ;
if(flowContext.resourceInstance == null) {
final Integer serverId = flowContext.backendResource.getInstanceId() ;
existingDTO = appdefBoss.findById(flowContext.subject, AppdefEntityID.newServerID(serverId));
}else {
existingDTO = ((Server)flowContext.resourceInstance).getServerValue() ;
}//EO else if the backend resource was loaded
return existingDTO ;
}//EOM
protected final void updateResourceInstance(final AppdefResourceValue newDTO, final AppdefBoss appdefBoss, final AuthzSubject subject) throws Exception {
appdefBoss.updateServer(subject, (ServerValue)newDTO, null/*cprops*/) ;
}//EOM
},//EO SERVER
SERVICE(AppdefEntityConstants.APPDEF_TYPE_SERVICE, ServiceValue.class) {
protected AppdefResourceValue loadExistingDTO(final AppdefBoss appdefBoss, final Context flowContext) throws Exception {
final Integer serviceId = flowContext.backendResource.getInstanceId() ;
return appdefBoss.findById(flowContext.subject, AppdefEntityID.newServiceID(serviceId)) ;
}//EOM
protected final void updateResourceInstance(final AppdefResourceValue newDTO, final AppdefBoss appdefBoss, final AuthzSubject subject) throws Exception {
appdefBoss.updateService(subject, (ServiceValue)newDTO, null/*cprops*/) ;
}//EOM
},//EO SERVER
RESOURCE(-999){
};//EO RESOURCE
/**
*
* @param resourceID naturalID/internal ID
* @param resourceManager
* @return
*/
Resource getResourceByNaturalID(final Context flowContext) throws Exception{
throw new UnsupportedOperationException("Resource Of Type " + this.name() + " does not support find by natural ID") ;
}//EOM
Resource getResourceByInternalID(final Context flowContext) {
final int iInternalResourceID = Integer.parseInt(flowContext.internalID) ;
return flowContext.visitor.getResourceManager().findResourceById(iInternalResourceID) ;
}//EOM
Resource getResource(final Context flowContext) throws Exception{
Resource resource = null ;
if(flowContext.backendResource != null) {
resource = flowContext.backendResource ;
}else if(flowContext.internalID != null) {
resource = this.getResourceByInternalID(flowContext) ;
}else {
resource = this.getResourceByNaturalID(flowContext);
}//EO else if internal id was not provided
return resource ;
}//EOM
public void mergeResource(final Context flowContext) throws Exception {
final ResourceConfig resourceConfig = flowContext.currResource.getResourceConfig() ;
if(this.clsAppdefResourceValue == null || resourceConfig == null) return ;
final AppdefBoss appdefBoss = flowContext.getVisitor().getAppdefBoss() ;
//else if the resource config section was provided in the request
AppdefResourceValue existingDTO = null ;
final Map<String,String> inputProps = resourceConfig.getMapProps() ;
if(inputProps != null) {
//load the existing AppdefResourceValue
existingDTO = this.loadExistingDTO(appdefBoss, flowContext) ;
String value = null ;
Object oValue = null ;;
Object[] metadata = null ;
Method method = null ;
for(Map.Entry<String,Object[]> entry : this.cachedPropertiesMutators.entrySet()) {
if((value = inputProps.get(entry.getKey())) != null ) {
metadata = entry.getValue() ;
method = (Method) metadata[0] ;
//convert the value into the target type
oValue = conversionService.convert(value, STRING_DESCRIPTOR, (TypeDescriptor)metadata[1]);
method.invoke(existingDTO, oValue) ;
}//EO if input was provided for the given attribute
}
}//EO if the inputProps was not null
//now check whether there are multi-property section in the request and if
//so delegate to sub-classes
final Map<String,PropertyList> oneToManyProps = resourceConfig.getMapListProps() ;
if(oneToManyProps != null) {
//if the existingDTO was not yet loaded (i.e. no one-one properties
//do so now
if(existingDTO == null) {
existingDTO = this.loadExistingDTO(appdefBoss, flowContext) ;
}//EO the dtos were not yet initialized
this.mergeResource(inputProps, oneToManyProps, existingDTO, flowContext) ;
}//EO if there were oneToManyProps for the given resource in the request
//finally, if a DTO was created (i.e. potential modifications were found)
//invoke the respective udpateXXX
if(existingDTO != null) this.updateResourceInstance(existingDTO, appdefBoss, flowContext.subject);
}//EOM
protected AppdefResourceValue loadExistingDTO(final AppdefBoss appdefBoss, final Context flowContext) throws Exception {
throw new UnsupportedOperationException() ;
}//EOM
protected AppdefResourceValue mergeResource(final Map<String,String> inputProps, Map<String,PropertyList> oneToManyProps,
final AppdefResourceValue existingDTO, final Context flowContext) throws Exception {
return existingDTO ;
}//EOM
protected void updateResourceInstance(final AppdefResourceValue newDTO, final AppdefBoss appdefBoss, final AuthzSubject subject) throws Exception {
throw new UnsupportedOperationException() ;
}//EOM
private final static GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService() ;
private final static TypeDescriptor STRING_DESCRIPTOR = TypeDescriptor.valueOf(String.class) ;
private static final ResourceTypeStrategy[] cachedValues ;
private static final int iNoOfStrategies ;
private int appdefEntityType ;
private Class<? extends AppdefResourceValue> clsAppdefResourceValue ;
private Map<String,Object[]> cachedPropertiesMutators ;
static{
cachedValues = values() ;
iNoOfStrategies = cachedValues.length ;
}//EO static block
private final void initCachedPropertiesMutators() {
final Method[] methods = this.clsAppdefResourceValue.getDeclaredMethods() ;
Property propertyMetadata = null ;
try{
for(Method method : methods) {
propertyMetadata = method.getAnnotation(Property.class) ;
if(propertyMetadata != null) {
method.setAccessible(true) ;
this.cachedPropertiesMutators.put(propertyMetadata.value(), new Object[]{ method, TypeDescriptor.valueOf(method.getParameterTypes()[0]) }) ;
}//EO if defined
}//EO while there are more declared methods
}catch(Throwable t) {
t.printStackTrace() ;
throw new Error("Failed to initialize cachedPropertiesMutators for type " + this.name() + " from class " + this.clsAppdefResourceValue, t) ;
}//EO catch block
}//EOM
private ResourceTypeStrategy(final int appdefEntityType, final Class<? extends AppdefResourceValue> clsAppdefResourceValue) {
this(appdefEntityType) ;
this.clsAppdefResourceValue = clsAppdefResourceValue ;
if(clsAppdefResourceValue != null) {
this.cachedPropertiesMutators = new ConcurrentHashMap<String,Object[]>() ;
this.initCachedPropertiesMutators() ;
}//EO if the clsAppdefesourceValue was not null
}//EOM
private ResourceTypeStrategy(final int appdefEntityType) {
this.appdefEntityType = appdefEntityType ;
}//EOM
static final ResourceTypeStrategy valueOf(final int iStrategyType) {
return (iStrategyType >= iNoOfStrategies ? RESOURCE : cachedValues[iStrategyType]) ;
}//EOM
static final ResourceTypeStrategy valueOf(final ResourceTypeModel enumResourceType) {
return (enumResourceType == null ? RESOURCE : valueOf(enumResourceType.name()) ) ;
}//EOM
static final String getResourceIdentifier(final ResourceModel resource) {
final String resourceIdentifier = resource.getId() ;
return (resourceIdentifier == null || resourceIdentifier.isEmpty() ? resource.getNaturalID() : resourceIdentifier) ;
}//EOM
}//EOE
private final ResourceModel getAIResource(final String platformNaturalID, final ResourceTypeModel resourceType,
final int hierarchyDepth, final ResourceDetailsType[] responseMetadata) {
//TODO: NYI
return null ;
}//EOM
public final static class Context {
public Resource backendResource ;
public AppdefResource resourceInstance ;
public AppdefEntityID entityID ;
public AuthzSubject subject ;
public ConfigSchemaAndBaseResponse[] configResponses ;
public Properties cprops ;
public ResourceTypeStrategy resourceTypeStrategy ;
public ResourceTransfer visitor ;
public String internalID ;
public String naturalID ;
public ResourceTypeModel resourceType ;
public Set<ResourceDetailsTypeStrategy> resourceDetails ;
public ResourceModel currResource ;
//Resource resourceRoot ;
public Context(final AuthzSubject subject, final String naturalID, final ResourceTypeModel resourceType, final ResourceDetailsType[] responseMetadata, final ResourceTransfer visitor) {
this(subject, null/*internalID*/,responseMetadata, visitor) ;
this.naturalID = naturalID ;
this.resourceType = resourceType ;
}//EOM
Context(final AuthzSubject subject, final String internalID, final ResourceDetailsType[] responseMetadata, final ResourceTransfer visitor) {
this(subject, visitor) ;
this.internalID = internalID;
this.resourceDetails = ResourceDetailsTypeStrategy.valueOf(responseMetadata) ;
}//EOM
Context(final AuthzSubject subject, final ResourceTransfer visitor) {
this.subject = subject ;
this.visitor = visitor ;
this.configResponses = new ConfigSchemaAndBaseResponse[ProductPlugin.CONFIGURABLE_TYPES.length] ;
}//EOM
public final void setBackendResource(final Resource backendResource ) {
this.backendResource = backendResource ;
this.internalID = backendResource.getId() + "" ;
}//EOM
public final void setInputResource(final ResourceModel inputResource) {
this.currResource = inputResource ;
this.internalID = inputResource.getId() ;
this.naturalID = inputResource.getNaturalID() ;
}//EOM
public final void reset() {
this.backendResource = null ;
this.internalID = null ;
this.entityID = null ;
this.cprops = null ;
this.configResponses = new ConfigSchemaAndBaseResponse[ProductPlugin.CONFIGURABLE_TYPES.length] ;
this.resourceType = null ;
this.naturalID = null ;
this.currResource = null ;
this.resourceInstance = null ;
this.resourceTypeStrategy = null ;
}//EOM
public ResourceTransfer getVisitor() {
return this.visitor;
}
}//EO inner class Context
@Transactional (readOnly=true)
public RegisteredResourceBatchResponse getResources(ApiMessageContext messageContext,
ResourceDetailsType[] responseMetadata,
int hierarchyDepth)
throws PermissionException, NotFoundException {
final boolean debug = log.isDebugEnabled();
final StopWatch watch = new StopWatch();
final RegisteredResourceBatchResponse res = new RegisteredResourceBatchResponse(errorHandler);
if (responseMetadata==null) {
log.warn("illegal request");
throw errorHandler.newWebApplicationException(
Response.Status.BAD_REQUEST, ExceptionToErrorCodeMapper.ErrorCode.BAD_REQ_BODY);
}
final List<ResourceDetailsType> responseMetadataList = Arrays.asList(responseMetadata);
if (hierarchyDepth < 0) {
log.warn("hierarchy Depth cannot be < 0");
throw errorHandler.newWebApplicationException(
Response.Status.NOT_ACCEPTABLE, ExceptionToErrorCodeMapper.ErrorCode.BAD_REQ_BODY);
}
final AuthzSubject authzSubject = messageContext.getAuthzSubject();
if (debug) watch.markTimeBegin("findViewablePSSResources");
final Set<Integer> viewable = permissionManager.findViewablePSSResources(authzSubject);
if (debug) watch.markTimeEnd("findViewablePSSResources");
final List<Resource> platformResources = getPlatformsFromResourceIds(viewable);
if (debug) watch.markTimeBegin("getResourceToChildren");
final Map<Resource, Collection<Resource>> resourceToChildren =
getResourceToChildren(viewable, platformResources, hierarchyDepth);
if (debug) watch.markTimeEnd("getResourceToChildren");
if (debug) watch.markTimeBegin("getResourceConfig");
final Map<Resource, ConfigResponse> config =
getResourceConfig(authzSubject, responseMetadataList, resourceToChildren.keySet());
if (debug) watch.markTimeEnd("getResourceConfig");
final Map<Resource, Collection<Ip>> ipInfo = getIpInfo(responseMetadataList, platformResources);
if (debug) watch.markTimeBegin("getResourceConfigProps");
final Map<AppdefEntityID, Properties> cProps =
getResourceConfigProps(responseMetadataList);
if (debug) watch.markTimeEnd("getResourceConfigProps");
final List<ResourceModel> resources = new ArrayList<ResourceModel>(platformResources.size());
for (final Resource platformResource : platformResources) {
ResourceModel model = resourceMapper.toResource(platformResource);
resources.add(model);
setAllChildren(model, platformResource, resourceToChildren, config, cProps, ipInfo);
}
res.setResources(resources);
if (debug) log.debug(watch);
return res;
}
private Map<AppdefEntityID, Properties> getResourceConfigProps(List<ResourceDetailsType> responseMetadataList) {
if (!responseMetadataList.contains(ResourceDetailsType.VIRTUALDATA) &&
!responseMetadataList.contains(ResourceDetailsType.ALL)) {
return Collections.emptyMap();
}
return cpropManager.getAllEntries(HQConstants.VCUUID, HQConstants.MOID);
}
private Map<Resource, Collection<Ip>> getIpInfo(List<ResourceDetailsType> responseMetadataList,
Collection<Resource> platformResources) {
if (!responseMetadataList.contains(ResourceDetailsType.PROPERTIES) &&
!responseMetadataList.contains(ResourceDetailsType.ALL)) {
return Collections.emptyMap();
}
return ipManager.getIps(platformResources);
}
private Map<Resource, ConfigResponse> getResourceConfig(AuthzSubject subject, List<ResourceDetailsType> responseMetadataList,
Set<Resource> resources) {
if (!responseMetadataList.contains(ResourceDetailsType.PROPERTIES) &&
!responseMetadataList.contains(ResourceDetailsType.ALL)) {
return Collections.emptyMap();
}
return configManager.getConfigResponses(resources, true);
}
private void setAllChildren(ResourceModel model, Resource platformResource,
Map<Resource, Collection<Resource>> resourceToChildren,
Map<Resource, ConfigResponse> config, Map<AppdefEntityID, Properties> cProps,
Map<Resource, Collection<Ip>> ipInfo) {
Collection<Resource> tmp;
addResourceConfig(platformResource, model, config, cProps, ipInfo);
if (null == (tmp = resourceToChildren.get(platformResource)) || tmp.isEmpty()) {
return;
}
for (final Resource child : tmp) {
final ResourceModel childModel = resourceMapper.toResource(child);
model.addSubResource(childModel);
setAllChildren(childModel, child, resourceToChildren, config, cProps, ipInfo);
}
}
private void addResourceConfig(Resource r, ResourceModel resourceModel, Map<Resource, ConfigResponse> configMap,
Map<AppdefEntityID, Properties> cProps, Map<Resource, Collection<Ip>> ipInfo) {
final ConfigResponse configResponse = configMap.get(r);
@SuppressWarnings("unchecked")
final Map<String, String> config = (configResponse == null) ?
new HashMap<String, String>() : configResponse.getConfig();
final AppdefEntityID aeid = AppdefUtil.newAppdefEntityId(r);
Properties properties = cProps.get(aeid);
properties = (properties == null) ? new Properties() : properties;
Object prop = properties.get(HQConstants.VCUUID);
if (prop != null) {
config.put(HQConstants.VCUUID, prop.toString());
}
prop = properties.get(HQConstants.MOID);
if (prop != null) {
config.put(HQConstants.MOID, prop.toString());
}
ResourceConfig resourceConfig = resourceModel.getResourceConfig();
resourceConfig = (resourceConfig == null) ? new ResourceConfig() : resourceConfig;
resourceConfig.setMapProps(config);
resourceModel.setResourceConfig(resourceConfig);
final Collection<Ip> ips = ipInfo.get(r);
if (ips != null && !ips.isEmpty()) {
Collection<ConfigurationValue> ipValues = new ArrayList<ConfigurationValue>(ips.size());
for (Ip ip : ips) {
ipValues.add(new ComplexIp(ip.getNetmask(), ip.getMacAddress(), ip.getAddress()));
}
resourceConfig.putMapListProps(IP_MAC_ADDRESS_KEY, ipValues);
}
}
@SuppressWarnings("unchecked")
private Map<Resource, Collection<Resource>> getResourceToChildren(Set<Integer> viewable,
List<Resource> platformResources,
int hierarchyDepth) {
final List<Resource> currResources = new ArrayList<Resource>(platformResources);
final Map<Resource, Collection<Resource>> rtn = new HashMap<Resource, Collection<Resource>>();
for (Resource r : platformResources) {
rtn.put(r, Collections.EMPTY_LIST);
}
final Map<Resource, Resource> systemResources = new HashMap<Resource, Resource>();
for (int i=2; i<=hierarchyDepth; i++) {
final Map<Resource, Collection<Resource>> childResources =
resourceManager.findChildResources(currResources, viewable, true);
rtn.putAll(childResources);
currResources.removeAll(childResources.keySet());
for (Resource r : currResources) {
rtn.put(r, new ArrayList<Resource>(0));
}
currResources.clear();
for (final Entry<Resource, Collection<Resource>> entry : childResources.entrySet()) {
final Resource parent = entry.getKey();
final Collection<Resource> children = entry.getValue();
for (final Iterator<Resource> it=children.iterator(); it.hasNext(); ) {
final Resource child = it.next();
currResources.add(child);
// EMPTY_LIST usage is a place holder to avoid extra overhead where resources don't have child
// resources
rtn.put(child, Collections.EMPTY_LIST);
// remove place-holder resource so that Platform Services don't expose our internal implementation
// rather than exposing the system resource which is a place-holder
// In other words:
// desired output is "Platform --> Services"
// in HQ we store this relationship as "Platform --> System Server --> Services"
if (child.isSystem()) {
systemResources.put(child, parent);
it.remove();
}
}
}
}
// need to post process the data in order to map the platform services correctly
final List<Resource> toFetch = new ArrayList<Resource>();
for (final Iterator<Entry<Resource, Resource>> it=systemResources.entrySet().iterator(); it.hasNext(); ) {
final Entry<Resource, Resource> entry = it.next();
final Resource systemResource = entry.getKey();
final Resource parent = entry.getValue();
final Collection<Resource> children = rtn.remove(systemResource);
if (children != null && !children.isEmpty()) {
it.remove();
final Collection<Resource> collection = rtn.get(parent);
if (collection != null) {
collection.addAll(children);
}
} else if (children != null && children == Collections.EMPTY_LIST) {
toFetch.add(systemResource);
}
}
final Map<Resource, Collection<Resource>> systemResourceChildren =
resourceManager.findChildResources(toFetch, viewable, true);
for (final Entry<Resource, Resource> entry : systemResources.entrySet()) {
final Resource systemResource = entry.getKey();
final Resource parent = entry.getValue();
final Collection<Resource> children = systemResourceChildren.get(systemResource);
final Collection<Resource> parentChildren = rtn.get(parent);
if (parentChildren != null && children != null) {
parentChildren.addAll(children);
}
}
return rtn;
}
private List<Resource> getPlatformsFromResourceIds(Set<Integer> viewable) {
return new Transformer<Integer, Resource>() {
public Resource transform(Integer resourceId) {
final Resource r = resourceManager.getResourceById(resourceId);
if (r != null && !r.isInAsyncDeleteState() && AuthzConstants.authzPlatform.equals(r.getResourceType()
.getId())) {
return r;
}
return null;
}
}.transform(viewable);
}
@Transactional (readOnly=true)
public RegistrationID register(ApiMessageContext messageContext, ResourceDetailsType responseMetadata,
ResourceFilterRequest resourceFilterRequest)
throws PermissionException, NotFoundException {
AuthzSubject authzSubject = messageContext.getAuthzSubject();
this.permissionManager.checkIsSuperUser(authzSubject);
List<Filter<InventoryNotification,? extends FilteringCondition<?>>> userFilters =
resourceMapper.toResourceFilters(resourceFilterRequest, responseMetadata);
RegistrationID registrationID = new RegistrationID();
final HttpEndpointDefinition httpEndpointDefinition = resourceFilterRequest.getHttpEndpointDef();
final NotificationEndpoint endpoint = (httpEndpointDefinition == null) ? new DefaultEndpoint(registrationID
.getId()) : getHttpEndpoint(registrationID, httpEndpointDefinition);
final Integer authzSubjectId = authzSubject.getId();
notificationsTransfer.register(endpoint, ResourceDetailsType.valueOf(responseMetadata), authzSubjectId);
evaluator.register(endpoint, userFilters);
return registrationID;
}
public ExternalRegistrationStatus getRegistrationStatus(final ApiMessageContext messageContext,
final String registrationID) throws PermissionException,NotFoundException, UnknownEndpointException{
AuthzSubject authzSubject = messageContext.getAuthzSubject();
this.permissionManager.checkIsSuperUser(authzSubject);
FilterChain<InventoryNotification> filterChain = evaluator.getRegistration(registrationID);
NotificationsTransferImpl.EndpointStatusAndDefinition endpointStatusAndDefinition = this.notificationsTransfer.getEndointStatus(registrationID);
return new ExternalRegistrationStatus(endpointStatusAndDefinition.getEndpoint(),filterChain, registrationID, endpointStatusAndDefinition.getExternalEndpointStatus());
}
public void unregister(final ApiMessageContext messageContext,NotificationEndpoint endpoint) throws PermissionException {
AuthzSubject authzSubject = messageContext.getAuthzSubject();
this.permissionManager.checkIsSuperUser(authzSubject);
evaluator.unregisterAll(endpoint);
}
public ResourceMapper getResourceMapper() {
return this.resourceMapper;
}
public PlatformManager getPlatformManager() {
return this.platformManager;
}
public ResourceManager getResourceManager() {
return this.resourceManager;
}
public final AppdefBoss getAppdefBoss() { return this.appdepBoss ; }//EOM
private HttpEndpoint getHttpEndpoint(RegistrationID registrationID, HttpEndpointDefinition def) {
return new HttpEndpoint(registrationID.getId(), def.getUrl(), def.getUsername(), def.getPassword(),
def.getContentType(), def.getEncoding(), def.getBodyPrepend());
}
}//EOC