/*************************************************************************
* (c) Copyright 2017 Hewlett Packard Enterprise Development Company LP
*
* 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.
*
* 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, see http://www.gnu.org/licenses/.
************************************************************************/
package com.eucalyptus.portal.awsusage;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProvider;
import com.amazonaws.services.simpleworkflow.flow.DecisionContextProviderImpl;
import com.amazonaws.services.simpleworkflow.flow.WorkflowClock;
import com.amazonaws.services.simpleworkflow.flow.annotations.Asynchronous;
import com.amazonaws.services.simpleworkflow.flow.core.Promise;
import com.amazonaws.services.simpleworkflow.flow.core.TryCatchFinally;
import com.eucalyptus.component.annotation.ComponentPart;
import com.eucalyptus.portal.common.Portal;
import com.eucalyptus.portal.workflow.AwsUsageActivitiesClient;
import com.eucalyptus.portal.workflow.AwsUsageActivitiesClientImpl;
import com.eucalyptus.portal.workflow.BillingWorkflowState;
import com.eucalyptus.portal.workflow.ResourceUsageEventWorkflow;
import com.eucalyptus.simpleworkflow.common.client.Repeating;
import org.apache.log4j.Logger;
import java.util.Random;
@Repeating(value = ResourceUsageWorkflowStarter.class, sleepSeconds = 300)
@ComponentPart(Portal.class)
public class ResourceUsageEventWorkflowImpl implements ResourceUsageEventWorkflow {
private static Logger LOG =
Logger.getLogger( ResourceUsageEventWorkflowImpl.class );
final AwsUsageActivitiesClient client =
new AwsUsageActivitiesClientImpl();
private BillingWorkflowState state =
BillingWorkflowState.WORKFLOW_RUNNING;
TryCatchFinally task = null;
private DecisionContextProvider contextProvider =
new DecisionContextProviderImpl();
final WorkflowClock clock =
contextProvider.getDecisionContext().getWorkflowClock();
private final int ITERATION_PER_WORKFLOW = 1; // should be bound to limit workflow history
private final int FIRING_DELAY_SEC = 1200;
@Override
public void fireEvents() {
task = new TryCatchFinally() {
@Override
protected void doTry() throws Throwable {
fireEventsPeriodic(0);
}
@Override
protected void doCatch(Throwable e) throws Throwable {
state = BillingWorkflowState.WORKFLOW_FAILED;
LOG.error("Workflow for firing resource usage events failed: ", e);
}
@Override
protected void doFinally() throws Throwable {
if (state == BillingWorkflowState.WORKFLOW_RUNNING)
state = BillingWorkflowState.WORKFLOW_SUCCESS;
}
};
}
@Asynchronous
void fireEventsPeriodic(final int count, final Promise<?>... waitFor) {
if (count >= ITERATION_PER_WORKFLOW) {
return;
}
final Random rand = new Random();
final Promise<Void> volume = client.fireVolumeUsage(
startDaemonTimer( rand.nextInt(FIRING_DELAY_SEC)));
final Promise<Void> snapshot = client.fireSnapshotUsage(
startDaemonTimer( rand.nextInt(FIRING_DELAY_SEC)));
final Promise<Void> address = client.fireAddressUsage(
startDaemonTimer(rand.nextInt(FIRING_DELAY_SEC)));
final Promise<Void> s3object = client.fireS3ObjectUsage(
startDaemonTimer(rand.nextInt(FIRING_DELAY_SEC)));
final Promise<Void> loadbalancers = client.fireLoadBalancerUsage(
startDaemonTimer(rand.nextInt(FIRING_DELAY_SEC)));
fireEventsPeriodic(count+1, volume, snapshot, address, s3object, loadbalancers);
}
@Asynchronous(daemon = true)
private Promise<Void> startDaemonTimer(int seconds) {
Promise<Void> timer = clock.createTimer(seconds);
return timer;
}
@Asynchronous
public BillingWorkflowState getState() {
return state;
}
}