/*
* RHQ Management Platform
* Copyright (C) 2005-2014 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.plugins.jbossas5;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jboss.deployers.spi.management.ManagementView;
import org.jboss.deployers.spi.management.deploy.DeploymentManager;
import org.jboss.deployers.spi.management.deploy.DeploymentProgress;
import org.jboss.deployers.spi.management.deploy.DeploymentStatus;
import org.jboss.managed.api.ComponentType;
import org.jboss.managed.api.ManagedComponent;
import org.jboss.managed.api.ManagedDeployment;
import org.jboss.managed.api.ManagedOperation;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.managed.api.RunState;
import org.jboss.metatype.api.values.ArrayValue;
import org.jboss.metatype.api.values.CollectionValue;
import org.jboss.metatype.api.values.CompositeValue;
import org.jboss.metatype.api.values.EnumValue;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.SimpleValue;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.plugins.jbossas5.util.ConversionUtils;
import org.rhq.plugins.jbossas5.util.DebugUtils;
import org.rhq.plugins.jbossas5.util.DeploymentUtils;
import org.rhq.plugins.jbossas5.util.ResourceComponentUtils;
import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
/**
* Service ResourceComponent for all {@link ManagedComponent}s in a Profile.
*
* @author Ian Springer
* @author Jason Dobies
* @author Mark Spritzler
*/
public class ManagedComponentComponent extends AbstractManagedComponent implements ConfigurationFacet,
DeleteResourceFacet, OperationFacet, MeasurementFacet {
private static final Log LOG = LogFactory.getLog(ManagedComponentComponent.class);
public static interface Config {
String COMPONENT_TYPE = "componentType";
String COMPONENT_SUBTYPE = "componentSubtype";
String COMPONENT_NAME = "componentName";
String TEMPLATE_NAME = "templateName";
String COMPONENT_NAME_PROPERTY = "componentNameProperty";
}
protected static final char PREFIX_DELIMITER = '|';
/**
* The availability refresh interval specifies a duration that if exceeded means a managed
* component refresh is needed to perform an availability check. That duration is set
* to 15 minutes.
*/
private static final long AVAIL_REFRESH_INTERVAL = 1000 * 60 * 15; // 15 minutes
private long availRefreshInterval = AVAIL_REFRESH_INTERVAL;
/**
* The ManagedComponent is fetched from the server in {@link #getManagedComponent} throughout
* the life cycle of this resource component. For example during metrics collections
* when getValues() is invoked, getManagedComponent() is called. Any time getManagedComponent()
* is called the lastComponentRefresh timestamp is updated. This timestamp is used in
* {@link #getAvailability} to determine whether or not a component is needed to
* perform an availability check.
*/
private volatile long lastComponentRefresh = 0L;
// The last known runState for the component. This is used to determine the result of getAvailability(). We
// do *not* cache the entire ManagedComponent because it is potentially a huge object that would eat too much memory.
private RunState runState;
private String componentName;
private ComponentType componentType;
// ResourceComponent Implementation --------------------------------------------
@Override
public AvailabilityType getAvailability() {
long timeSinceComponentRefresh = System.currentTimeMillis() - lastComponentRefresh;
boolean refresh = timeSinceComponentRefresh > availRefreshInterval;
if (runState == null || refresh) {
if (LOG.isDebugEnabled() && runState != null && lastComponentRefresh > 0L) {
LOG.debug("The availability refresh interval for [resourceKey: "
+ getResourceContext().getResourceKey() + ", type: " + componentType + ", name: " + componentName
+ "] has been exceeded by " + (timeSinceComponentRefresh - availRefreshInterval)
+ " ms. Reloading managed component...");
}
ManagedComponent managedComponent = getManagedComponent();
runState = managedComponent.getRunState();
}
return getAvailabilityForRunState(runState);
}
protected AvailabilityType getAvailabilityForRunState(RunState runState) {
if (runState == RunState.RUNNING) {
return AvailabilityType.UP;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Returning DOWN avail for " + componentType + " component '" + componentName
+ "' with runState [" + runState + "].");
}
return AvailabilityType.DOWN;
}
}
@Override
public void start(ResourceContext<ProfileServiceComponent<?>> resourceContext) throws Exception {
super.start(resourceContext);
componentType = ConversionUtils.getComponentType(getResourceContext().getResourceType());
Configuration pluginConfig = resourceContext.getPluginConfiguration();
componentName = pluginConfig.getSimple(Config.COMPONENT_NAME).getStringValue();
initAvailRefreshInterval(resourceContext);
if (LOG.isTraceEnabled()) {
LOG.trace("Started ResourceComponent for " + getResourceDescription() + ", managing " + this.componentType
+ " component '" + this.componentName + "'.");
}
}
@Override
public void stop() {
super.stop();
}
// ConfigurationComponent Implementation --------------------------------------------
@Override
public Configuration loadResourceConfiguration() {
Configuration resourceConfig;
ManagedComponent managedComponent = getManagedComponent();
try {
Map<String, ManagedProperty> managedProperties = managedComponent.getProperties();
Map<String, PropertySimple> customProps = ResourceComponentUtils.getCustomProperties(getResourceContext()
.getPluginConfiguration());
if (LOG.isDebugEnabled()) {
LOG.debug("*** AFTER LOAD:\n" + DebugUtils.convertPropertiesToString(managedProperties));
}
resourceConfig = ConversionUtils.convertManagedObjectToConfiguration(managedProperties, customProps,
getResourceContext().getResourceType());
} catch (Exception e) {
RunState runState = managedComponent.getRunState();
if (runState == RunState.RUNNING) {
LOG.error("Failed to load configuration for " + getResourceDescription() + ".", e);
} else if (LOG.isDebugEnabled()) {
LOG.debug("Failed to load configuration for " + getResourceDescription()
+ ", but managed component is not in the RUNNING state.", e);
}
throw new RuntimeException(ThrowableUtil.getAllMessages(e));
}
return resourceConfig;
}
/**
* updates resource configuration, but only changes. This is done by loading configuration first and then comparing
* all the simple properties (if existing and new value equals, property is skipped)
*
* @param configurationUpdateReport report
*/
public void updateResourceConfigurationChangesOnly(ConfigurationUpdateReport configurationUpdateReport) {
Configuration existing = loadResourceConfiguration();
Configuration config = configurationUpdateReport.getConfiguration();
ConfigurationDefinition configDefCopy = copyConfigurationDefinition(getResourceContext().getResourceType()
.getResourceConfigurationDefinition());
// filter out unchanged values
for (Property prop : config.getAllProperties().values()) {
if (prop instanceof PropertySimple) {
if (prop instanceof PropertySimple) {
PropertySimple propSimple = (PropertySimple) prop;
String val1 = propSimple.getStringValue();
String val2 = existing.getSimpleValue(propSimple.getName());
if (val1 == null && val2 == null) {
configDefCopy.getPropertyDefinitions().remove(propSimple.getName());
}
if (val1 != null) {
if (val1.equals(val2)) {
configDefCopy.getPropertyDefinitions().remove(propSimple.getName());
}
} else if (val2 != null) {
if (val2.equals(val1)) {
configDefCopy.getPropertyDefinitions().remove(propSimple.getName());
}
}
}
}
}
updateResourceConfiguration(configurationUpdateReport, configDefCopy);
}
/**
* update resource configuration. Given resourceConfigurationDefinition defines which properties will be updated. Use this
* method in case you don't want to update all properties defined by resource type and supply resourceConfigurationDefinition
* consisting of stuff you want.
* @param configurationUpdateReport
* @param resourceConfigurationDefinition
*/
protected void updateResourceConfiguration(ConfigurationUpdateReport configurationUpdateReport,
ConfigurationDefinition resourceConfigurationDefinition) {
Configuration resourceConfig = configurationUpdateReport.getConfiguration();
Configuration pluginConfig = getResourceContext().getPluginConfiguration();
try {
ManagedComponent managedComponent = getManagedComponent();
Map<String, ManagedProperty> managedProperties = managedComponent.getProperties();
Map<String, PropertySimple> customProps = ResourceComponentUtils.getCustomProperties(pluginConfig);
if (LOG.isDebugEnabled()) {
LOG.debug("*** BEFORE UPDATE:\n" + DebugUtils.convertPropertiesToString(managedProperties));
}
ConversionUtils.convertConfigurationToManagedProperties(managedProperties, resourceConfig,
resourceConfigurationDefinition, customProps, true);
if (LOG.isDebugEnabled()) {
LOG.debug("*** AFTER UPDATE:\n" + DebugUtils.convertPropertiesToString(managedProperties));
}
updateComponent(managedComponent);
configurationUpdateReport.setStatus(ConfigurationUpdateStatus.SUCCESS);
} catch (Exception e) {
LOG.error("Failed to update configuration for " + getResourceDescription() + ".", e);
configurationUpdateReport.setStatus(ConfigurationUpdateStatus.FAILURE);
configurationUpdateReport.setErrorMessage(ThrowableUtil.getAllMessages(e));
}
}
@Override
public void updateResourceConfiguration(ConfigurationUpdateReport configurationUpdateReport) {
updateResourceConfiguration(configurationUpdateReport, getResourceContext().getResourceType()
.getResourceConfigurationDefinition());
}
// DeleteResourceFacet Implementation --------------------------------------------
@Override
public void deleteResource() throws Exception {
DeploymentManager deploymentManager = getConnection().getDeploymentManager();
if (!deploymentManager.isRedeploySupported())
throw new UnsupportedOperationException("Deletion of " + getResourceContext().getResourceType().getName()
+ " Resources is not currently supported.");
ManagedComponent managedComponent = getManagedComponent();
if (LOG.isDebugEnabled()) {
LOG.debug("Removing " + getResourceDescription() + " with component " + toString(managedComponent) + "...");
}
ManagementView managementView = getConnection().getManagementView();
managementView.removeComponent(managedComponent);
ManagedDeployment parentDeployment = managedComponent.getDeployment();
if (parentDeployment.getComponents().size() > 1 || !parentDeployment.getChildren().isEmpty()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Redeploying parent deployment '" + parentDeployment.getName()
+ "' in order to complete removal of component " + toString(managedComponent) + "...");
}
DeploymentProgress progress = deploymentManager.redeploy(parentDeployment.getName());
DeploymentStatus status = DeploymentUtils.run(progress);
if (status.isFailed()) {
LOG.error("Failed to redeploy parent deployment '" + parentDeployment.getName()
+ "during removal of component " + toString(managedComponent)
+ " - removal may not persist when the app server is restarted.", status.getFailure());
}
} else {
//this is the last component of the deployment and nothing would be left there after
//the component was removed. Let's just undeploy it in addition to removing the component.
//This will make sure that the deployment doesn't leave behind any defunct config files, etc.
if (LOG.isDebugEnabled()) {
LOG.debug("Undeploying parent deployment '" + parentDeployment.getName()
+ "' in order to complete removal of component " + toString(managedComponent) + "...");
}
parentDeployment = managementView.getDeployment(parentDeployment.getName());
DeploymentProgress progress = deploymentManager.remove(parentDeployment.getName());
DeploymentStatus status = DeploymentUtils.run(progress);
if (status.isFailed()) {
LOG.error("Failed to undeploy parent deployment '" + parentDeployment.getName()
+ "during removal of component " + toString(managedComponent)
+ " - removal may not persist when the app server is restarted.", status.getFailure());
}
}
managementView.load();
}
// OperationFacet Implementation --------------------------------------------
@Override
public OperationResult invokeOperation(String name, Configuration parameters) throws Exception {
return invokeOperation(getManagedComponent(), name, parameters);
}
protected OperationResult invokeOperation(ManagedComponent managedComponent, String name, Configuration parameters)
throws Exception {
OperationDefinition operationDefinition = getOperationDefinition(name);
ManagedOperation managedOperation = getManagedOperation(managedComponent, operationDefinition);
// Convert parameters into MetaValue array.
MetaValue[] parameterMetaValues = ConversionUtils.convertOperationsParametersToMetaValues(managedOperation,
parameters, operationDefinition);
// invoke() takes a varargs, so we need to pass an empty array, rather than null.
MetaValue resultMetaValue = managedOperation.invoke(parameterMetaValues);
OperationResult result = new OperationResult();
// Convert result MetaValue to corresponding Property type.
ConversionUtils.convertManagedOperationResults(managedOperation, resultMetaValue, result.getComplexResults(),
operationDefinition);
// If this is a lifecycle operation ask for an avail check
boolean availCheck = name.toLowerCase().equals("stop") || name.toLowerCase().contains("start");
if (availCheck) {
getResourceContext().getAvailabilityContext().requestAvailabilityCheck();
}
return result;
}
// MeasurementFacet Implementation --------------------------------------------
@Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
getValues(getManagedComponent(), report, metrics);
}
protected void getValues(ManagedComponent managedComponent, MeasurementReport report,
Set<MeasurementScheduleRequest> metrics) throws Exception {
RunState runState = managedComponent.getRunState();
for (MeasurementScheduleRequest request : metrics) {
try {
String value = getMeasurement(managedComponent, request.getName());
addValueToMeasurementReport(report, request, value);
} catch (Exception e) {
if (runState == RunState.RUNNING) {
LOG.error("Failed to collect metric for " + request, e);
} else if (LOG.isDebugEnabled()) {
LOG.debug("Failed to collect metric for " + request
+ ", but managed component is not in the RUNNING state.", e);
}
}
}
}
protected String getMeasurement(ManagedComponent component, String metricName) throws Exception {
if ("runState".equals(metricName)) {
return component.getRunState().name();
} else {
Object value = getSimpleValue(component, metricName);
return value == null ? null : toString(value);
}
}
protected void updateComponent(ManagedComponent managedComponent) throws Exception {
if (LOG.isTraceEnabled()) {
LOG.trace("Updating " + getResourceDescription() + " with component " + toString(managedComponent) + "...");
}
ManagementView managementView = getConnection().getManagementView();
managementView.updateComponent(managedComponent);
managementView.load();
}
// ------------------------------------------------------------------------------
/**
* The name of the measurement schedule request (i.e. the metric name) can be in one of two forms:
* <p/>
* [prefix'|']simplePropertyName (e.g. "maxTime" or "ThreadPool|currentThreadCount")
* [prefix'|']compositePropertyName'.'key (e.g. "consumerCount" or "messageStatistics.count")
*
* @param managedComponent a managed component
* @param request a measurement schedule request
* @return the metric value
*/
@Nullable
protected Object getSimpleValue(ManagedComponent managedComponent, MeasurementScheduleRequest request) {
String metricName = request.getName();
return getSimpleValue(managedComponent, metricName);
}
@Nullable
protected Object getSimpleValue(ManagedComponent managedComponent, String metricName) {
int pipeIndex = metricName.indexOf(PREFIX_DELIMITER);
// Remove the prefix if there is one (e.g. "ThreadPool|currentThreadCount" -> "currentThreadCount").
String compositePropName = (pipeIndex == -1) ? metricName : metricName.substring(pipeIndex + 1);
int dotIndex = compositePropName.indexOf('.');
String metricPropName = (dotIndex == -1) ? compositePropName : compositePropName.substring(0, dotIndex);
ManagedProperty metricProp = managedComponent.getProperty(metricPropName);
if (metricProp == null) {
return null;
}
MetaValue metaValue;
if (dotIndex == -1) {
metaValue = metricProp.getValue();
} else {
CompositeValue compositeValue = (CompositeValue) metricProp.getValue();
String key = compositePropName.substring(dotIndex + 1);
metaValue = compositeValue.get(key);
}
return getInnerValue(metaValue);
}
/**
* The name of the measurement schedule request (i.e. the metric name) can be in one of two forms:
* <p/>
* [prefix'|']simplePropertyName (e.g. "maxTime" or "ThreadPool|currentThreadCount")
* [prefix'|']compositePropertyName'.'key (e.g. "consumerCount" or "messageStatistics.count")
*
* @param managedComponent a managed component
* @param request a measurement schedule request
* @return the metric value
*/
@Nullable
protected ManagedProperty getManagedProperty(ManagedComponent managedComponent, MeasurementScheduleRequest request) {
String metricName = request.getName();
int pipeIndex = metricName.indexOf(PREFIX_DELIMITER);
// Remove the prefix if there is one (e.g. "ThreadPool|currentThreadCount" -> "currentThreadCount").
String compositePropName = (pipeIndex == -1) ? metricName : metricName.substring(pipeIndex + 1);
int dotIndex = compositePropName.indexOf('.');
String metricPropName = (dotIndex == -1) ? compositePropName : compositePropName.substring(0, dotIndex);
return managedComponent.getProperty(metricPropName);
}
// TODO: Move this to a utility class.
@Nullable
protected static Object getInnerValue(MetaValue metaValue) {
if (metaValue == null) {
return null;
}
Object value;
if (metaValue.getMetaType().isSimple()) {
SimpleValue simpleValue = (SimpleValue) metaValue;
value = simpleValue.getValue();
} else if (metaValue.getMetaType().isEnum()) {
EnumValue enumValue = (EnumValue) metaValue;
value = enumValue.getValue();
} else if (metaValue.getMetaType().isArray()) {
ArrayValue arrayValue = (ArrayValue) metaValue;
value = arrayValue.getValue();
} else if (metaValue.getMetaType().isCollection()) {
CollectionValue collectionValue = (CollectionValue) metaValue;
List<Object> list = new ArrayList<Object>();
for (MetaValue element : collectionValue.getElements()) {
list.add(getInnerValue(element));
}
value = list;
} else {
value = metaValue.toString();
}
return value;
}
protected void addValueToMeasurementReport(MeasurementReport report, MeasurementScheduleRequest request,
Object value) {
if (value == null) {
return;
}
String stringValue = toString(value);
DataType dataType = request.getDataType();
switch (dataType) {
case MEASUREMENT:
try {
MeasurementDataNumeric dataNumeric = new MeasurementDataNumeric(request, Double.valueOf(stringValue));
report.addData(dataNumeric);
} catch (NumberFormatException e) {
LOG.error("Profile service did not return a numeric value as expected for metric [" + request.getName()
+ "] - value returned was " + value + ".", e);
}
break;
case TRAIT:
MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, stringValue);
report.addData(dataTrait);
break;
default:
throw new IllegalStateException("Unsupported measurement data type: " + dataType);
}
}
protected ComponentType getComponentType() {
return componentType;
}
protected String getComponentName() {
return componentName;
}
/**
* This method should most likely not be overridden. Instead, override {@link #getManagedComponent(ManagementView)}.
* <br/><br/>
* IMPORTANT!!! The returned ManagedComponent SHOULD NOT be cached in the instance. It is potentially a memory hog.
*
* @return The ManagedComponent
* @throws RuntimeException if fetching the ManagementView or getting the component fails
* @throws IllegalStateException if the managedComponent is null/not found
*/
@NotNull
protected ManagedComponent getManagedComponent() {
ManagedComponent managedComponent;
try {
ManagementView managementView = getConnection().getManagementView();
managedComponent = getManagedComponent(managementView);
} catch (Exception e) {
throw new RuntimeException("Failed to load [" + this.componentType + "] ManagedComponent ["
+ this.componentName + "].", e);
}
// Even if not found, update the refresh time. It will avoid too many costly, and potentially fruitless, fetches
lastComponentRefresh = System.currentTimeMillis();
if (managedComponent == null) {
throw new IllegalStateException("Failed to find [" + this.componentType + "] ManagedComponent named ["
+ this.componentName + "].");
}
if (LOG.isTraceEnabled()) {
LOG.trace("Retrieved " + toString(managedComponent) + ".");
}
return managedComponent;
}
/**
* This is an override point. When actually fetching the managed component, this entry point should not be
* used. Instead, access should be via {@link #getManagedComponent()}.
*
* @param managementView for querying profile service
* @return the ManagedComponent. Null if not found.
* @throws Exception if there is a problem getting the component.
*/
protected ManagedComponent getManagedComponent(ManagementView managementView) throws Exception {
if (null == managementView) {
throw new IllegalArgumentException("managementView can not be null");
}
return managementView.getComponent(this.componentName, this.componentType);
}
@NotNull
private OperationDefinition getOperationDefinition(String operationName) {
ResourceType resourceType = getResourceContext().getResourceType();
OperationDefinition operationDefinition = ResourceTypeUtils.getOperationDefinition(resourceType, operationName);
if (operationDefinition == null)
throw new IllegalStateException("Operation named '" + operationName
+ "' is not defined for Resource type '" + resourceType.getName() + "' in the '"
+ resourceType.getPlugin() + "' plugin's descriptor.");
return operationDefinition;
}
@NotNull
private ManagedOperation getManagedOperation(ManagedComponent managedComponent,
OperationDefinition operationDefinition) {
Set<ManagedOperation> operations = managedComponent.getOperations();
for (ManagedOperation operation : operations) {
ConfigurationDefinition paramsConfigDef = operationDefinition.getParametersConfigurationDefinition();
int paramCount = (paramsConfigDef != null) ? paramsConfigDef.getPropertyDefinitions().size() : 0;
if (operation.getName().equals(operationDefinition.getName())
&& (operation.getParameters().length == paramCount))
return operation;
}
throw new IllegalStateException("ManagedOperation named '" + operationDefinition.getName()
+ "' not found on ManagedComponent [" + managedComponent + "].");
}
private static String toString(ManagedComponent managedComponent) {
Map<String, ManagedProperty> properties = managedComponent.getProperties();
return managedComponent.getClass().getSimpleName() + "@" + System.identityHashCode(managedComponent) + "["
+ "type=" + managedComponent.getType() + ", name=" + managedComponent.getName() + ", properties="
+ properties.getClass().getSimpleName() + "@" + System.identityHashCode(properties) + "]";
}
private static String toString(@NotNull Object value) {
if (value.getClass().isArray()) {
StringBuilder buffer = new StringBuilder();
int lastIndex = Array.getLength(value) - 1;
for (int i = 0; i < Array.getLength(value); i++) {
buffer.append(String.valueOf(Array.get(value, i)));
if (i == lastIndex) {
break;
}
buffer.append(", ");
}
return buffer.toString();
} else {
return value.toString();
}
}
private void initAvailRefreshInterval(ResourceContext<ProfileServiceComponent<?>> context) {
ProfileServiceComponent<?> component = context.getParentResourceComponent();
while (component != null) {
if (component instanceof ApplicationServerComponent) {
break;
}
component = (ProfileServiceComponent<?>) component.getResourceContext().getParentResourceComponent();
}
if (component == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to find parent " + ApplicationServerComponent.class.getSimpleName()
+ ". Using default component refresh interval, " + AVAIL_REFRESH_INTERVAL + " ms");
}
return;
}
String interval = component.getResourceContext().getPluginConfiguration()
.getSimpleValue("serviceAvailabilityRefreshInterval", Long.toString(AVAIL_REFRESH_INTERVAL));
availRefreshInterval = Long.parseLong(interval) * 1000 * 60;
}
static ConfigurationDefinition copyConfigurationDefinition(ConfigurationDefinition configurationDefinition) {
ConfigurationDefinition configDefCopy = new ConfigurationDefinition(configurationDefinition.getName(),
configurationDefinition.getDescription());
configDefCopy.setConfigurationFormat(configurationDefinition.getConfigurationFormat());
configDefCopy.setPropertyDefinitions(new HashMap<String, PropertyDefinition>(configurationDefinition
.getPropertyDefinitions()));
return configDefCopy;
}
}