/************************************************************************* * (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.monthlyreport; 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.BillingWorkflowState; import com.eucalyptus.portal.workflow.MonthlyReportActivitiesClient; import com.eucalyptus.portal.workflow.MonthlyReportActivitiesClientImpl; import com.eucalyptus.portal.workflow.MonthlyReportGeneratorWorkflow; import com.eucalyptus.portal.workflow.MonthlyUsageRecord; import com.eucalyptus.simpleworkflow.common.client.Daily; import com.google.common.collect.Lists; import org.apache.log4j.Logger; import java.util.Date; import java.util.List; // Delay execution after 5 minute of a new day because monthly report depends on AWS usage report // which is being updated at 0 minute of every hour. @Daily(value = MonthlyReportWorkflowStarter.class, hour = 0, minute = 5) @ComponentPart(Portal.class) public class MonthlyReportGeneratorWorkflowImpl implements MonthlyReportGeneratorWorkflow { private static Logger LOG = Logger.getLogger( MonthlyReportGeneratorWorkflowImpl.class ); final MonthlyReportActivitiesClient client = new MonthlyReportActivitiesClientImpl(); private BillingWorkflowState state = BillingWorkflowState.WORKFLOW_RUNNING; TryCatchFinally task = null; private String year = null; private String month = null; private Date reportUntil = null; @Override public void generateMonthlyReport(final String year, final String month, final Date until) { this.year = year; this.month = month; this.reportUntil = until; task = new TryCatchFinally() { @Override protected void doTry() throws Throwable { doGenerate(); } @Override protected void doCatch(Throwable e) throws Throwable { // no cleanup is necessary state = BillingWorkflowState.WORKFLOW_FAILED; LOG.error("Workflow generating monthly AWS usage report has failed: ", e); } @Override protected void doFinally() throws Throwable { if (state == BillingWorkflowState.WORKFLOW_RUNNING) state = BillingWorkflowState.WORKFLOW_SUCCESS; } }; } @Asynchronous public void doGenerate() { final Promise<List<String>> accounts = client.listCandidateAccounts(); generateForAccounts(accounts); } @Asynchronous public void generateForAccounts(Promise<List<String>> accounts) { for (final String accountId : accounts.get()) { Promise<Void> run = Promise.Void(); for (final String service : Lists.newArrayList("AmazonEC2", "AmazonS3")) { final Promise<List<MonthlyUsageRecord>> records = client.transform( client.queryMonthlyAwsUsage(accountId, service, this.year, this.month, this.reportUntil) ); run = client.persist( Promise.asPromise(accountId), Promise.asPromise(this.year), Promise.asPromise(this.month), records, run // persist is serialized ); client.uploadToS3Bucket( Promise.asPromise(accountId), Promise.asPromise(this.year), Promise.asPromise(this.month), run); } } } @Override public BillingWorkflowState getState() { return state; } }