/*************************************************************************
* (c) Copyright 2017 Hewlett Packard Enterprise Development Company LP
* <p>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
* <p>
* 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.
* <p>
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
************************************************************************/
package com.eucalyptus.portal;
import com.eucalyptus.configurable.ConfigurableClass;
import com.eucalyptus.configurable.ConfigurableField;
import com.eucalyptus.configurable.ConfigurableProperty;
import com.eucalyptus.configurable.ConfigurablePropertyException;
import com.eucalyptus.configurable.PropertyChangeListener;
import com.eucalyptus.simpleworkflow.common.client.Config;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ConfigurableClass(root = "services.billing", description = "Parameters controlling billing service")
public class BillingProperties {
private static final String DEFAULT_SQS_CLIENT_CONFIG =
"{\"ConnectionTimeout\": 10000, \"MaxConnections\": 100}";
private static final String DEFAULT_SENSOR_QUEUE_ATTRIBUTES =
"{\"DelaySeconds\": \"0\", \"MaximumMessageSize\": \"262144\", " +
"\"MessageRetentionPeriod\": \"10800\", \"ReceiveMessageWaitTimeSeconds\": \"0\", " +
"\"VisibilityTimeout\": \"120\"}";
private static final String DEFAULT_SWF_ACTIVITY_WORKER_CONFIG =
"{\"PollThreadCount\": 4, \"TaskExecutorThreadPoolSize\": 32, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }";
private static final String DEFAULT_SWF_WORKFLOW_WORKER_CONFIG =
"{ \"DomainRetentionPeriodInDays\": 1, \"PollThreadCount\": 4, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }";
@ConfigurableField( description = "Enable billing's data collection and aggregation", initial = "true" )
public static Boolean ENABLED = Boolean.TRUE;
@ConfigurableField(
initial = DEFAULT_SQS_CLIENT_CONFIG,
description = "JSON configuration for the billing SQS client",
changeListener = ClientConfigurationValidatingChangeListener.class )
public static volatile String SQS_CLIENT_CONFIG = DEFAULT_SQS_CLIENT_CONFIG;
@ConfigurableField(
initial = DEFAULT_SENSOR_QUEUE_ATTRIBUTES,
description = "JSON attributes for the sensor queue",
changeListener = SensorQueueAttributesChangeListener.class)
public static String SENSOR_QUEUE_ATTRIBUTES = DEFAULT_SENSOR_QUEUE_ATTRIBUTES;
@ConfigurableField(
initial = "BillingDomain",
description = "The simple workflow service domain for billing",
changeListener = Config.NameValidatingChangeListener.class )
public static volatile String SWF_DOMAIN = "BillingDomain";
@ConfigurableField(
initial = "BillingTasks",
description = "The simple workflow service task list for billing",
changeListener = Config.NameValidatingChangeListener.class )
public static volatile String SWF_TASKLIST = "BillingTasks";
@ConfigurableField(
initial = DEFAULT_SWF_ACTIVITY_WORKER_CONFIG,
description = "JSON configuration for the billing workflow activity worker",
changeListener = Config.ActivityWorkerConfigurationValidatingChangeListener.class )
public static volatile String SWF_ACTIVITY_WORKER_CONFIG = DEFAULT_SWF_ACTIVITY_WORKER_CONFIG;
@ConfigurableField(
initial = DEFAULT_SWF_WORKFLOW_WORKER_CONFIG,
description = "JSON configuration for the billing workflow decision worker",
changeListener = Config.WorkflowWorkerConfigurationValidatingChangeListener.class )
public static volatile String SWF_WORKFLOW_WORKER_CONFIG = DEFAULT_SWF_WORKFLOW_WORKER_CONFIG;
public static String SENSOR_QUEUE_NAME = "BillingSensorQueue";
public static String INSTANCE_HOUR_SENSOR_QUEUE_NAME = "BillingInstanceHourSensorQueue";
public static final class ClientConfigurationValidatingChangeListener implements PropertyChangeListener {
@Override
public void fireChange(final ConfigurableProperty t, final Object newValue ) throws ConfigurablePropertyException {
if ( newValue != null && !newValue.toString( ).trim( ).isEmpty( ) ) try {
SimpleQueueClientManager.buildConfiguration( newValue.toString( ).trim( ) );
} catch ( final IllegalArgumentException e ) {
throw new ConfigurablePropertyException( e.getMessage( ) );
}
}
}
public static final class SensorQueueAttributesChangeListener implements PropertyChangeListener {
@Override
public void fireChange(final ConfigurableProperty t, final Object newValue ) throws ConfigurablePropertyException {
if ( newValue != null && !newValue.toString( ).trim( ).isEmpty( ) ) try {
SimpleQueueClientManager.getInstance().setQueueAttributes( SENSOR_QUEUE_NAME,
getQueueAttributes(newValue.toString()) );
} catch ( final IllegalArgumentException e ) {
throw new ConfigurablePropertyException( e.getMessage( ) );
} catch (final IOException e) {
throw new ConfigurablePropertyException( "Invalid JSON: "+ e.getMessage( ) );
} catch (final Exception e) {
throw new ConfigurablePropertyException( e.getMessage( ) );
}
}
}
public static Map<String, String> getQueueAttributes() throws IOException {
return getQueueAttributes(SENSOR_QUEUE_ATTRIBUTES);
}
public static Map<String, String> getQueueAttributes(final String strAttributes) throws IOException {
final ObjectMapper mapper = new ObjectMapper( );
final TypeReference<HashMap<String,String>> typeRef
= new TypeReference<HashMap<String,String>>() {};
return mapper.readValue(strAttributes.trim(), typeRef);
}
}