/************************************************************************* * Copyright 2009-2016 Eucalyptus Systems, Inc. * * 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/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.loadbalancing.workflow; import java.util.concurrent.CancellationException; import org.apache.log4j.Logger; 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.loadbalancing.common.LoadBalancing; import com.eucalyptus.loadbalancing.workflow.LoadBalancingActivitiesClient; import com.eucalyptus.loadbalancing.workflow.LoadBalancingActivitiesClientImpl; /** * @author Sang-Min Park (sangmin.park@hpe.com) * */ @ComponentPart(LoadBalancing.class) public class CreateLoadBalancerWorkflowImpl implements CreateLoadBalancerWorkflow { private static Logger LOG = Logger.getLogger( CreateLoadBalancerWorkflowImpl.class ); final LoadBalancingActivitiesClient client = new LoadBalancingActivitiesClientImpl(); TryCatchFinally task = null; Promise<Boolean> admission = null; Promise<String> roleName = null; Promise<String> instanceProfile = null; Promise<String> iamPolicy = null; Promise<SecurityGroupSetupActivityResult> securityGroup = null; Promise<CreateTagActivityResult> tag = null; private ElbWorkflowState state = ElbWorkflowState.WORKFLOW_RUNNING; @Override public void createLoadBalancer(final String accountId, final String loadbalancer, final String[] availabilityZones) { task = new TryCatchFinally() { @Override protected void doTry() throws Throwable { admission = doAdmission( client.createLbAdmissionControl(accountId, loadbalancer, availabilityZones)); roleName = client.iamRoleSetup(accountId, loadbalancer, admission); instanceProfile = client.instanceProfileSetup(Promise.asPromise(accountId), Promise.asPromise(loadbalancer), roleName); iamPolicy = client.iamPolicySetup(Promise.asPromise(accountId), Promise.asPromise(loadbalancer), roleName); securityGroup = client.securityGroupSetup(accountId, loadbalancer, admission); tag = client.createLbTagCreator(Promise.asPromise(accountId), Promise.asPromise(loadbalancer), getSecurityGroupId(securityGroup)); } @Override protected void doCatch(Throwable e) throws Throwable { if ( e instanceof CancellationException) { LOG.warn("Creating loadbalancer stops due to failed admission control"); state = ElbWorkflowState.WORKFLOW_CANCELLED; return; } // rollback activities Promise<Void> tagRollback = null; if ( tag!=null && tag.isReady() ) { tagRollback=client.createLbTagCreatorRollback(tag); } if ( securityGroup!=null && securityGroup.isReady()) { client.securityGroupSetupRollback(Promise.asPromise(accountId), Promise.asPromise(loadbalancer), securityGroup, tagRollback); } final LoadBalancingActivityException ex = Exceptions.lookupActivityException(e); if (ex != null && ex instanceof NotEnoughResourcesException) { state = ElbWorkflowState.WORKFLOW_FAILED .withReason("Not enough resources to create loadbalancer") .withStatusCode(400); } else if (ex != null && ex instanceof InvalidConfigurationRequestException) { state = ElbWorkflowState.WORKFLOW_FAILED .withReason("Requested configuration change is invalid") .withStatusCode(400); } else { state = ElbWorkflowState.WORKFLOW_FAILED; LOG.error("Failed to create the loadbalancer. Rollback completed", e); } } @Override protected void doFinally() throws Throwable { if (state == ElbWorkflowState.WORKFLOW_RUNNING) state = ElbWorkflowState.WORKFLOW_SUCCESS; } }; } @Asynchronous private Promise<String> getSecurityGroupId(Promise<SecurityGroupSetupActivityResult> securityGroup) { return Promise.asPromise(securityGroup.get().getCreatedGroupId()); } @Asynchronous private Promise<Boolean> doAdmission (Promise<Boolean> admissionControl) { if(admissionControl.get()) { return Promise.asPromise(true); } else { task.cancel(null); return Promise.asPromise(false); } } @Override public ElbWorkflowState getState() { return state; } }