/*
* Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.amazonaws.eclipse.elasticbeanstalk;
import static com.amazonaws.eclipse.elasticbeanstalk.ElasticBeanstalkPlugin.trace;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.wst.server.core.IModule;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.eclipse.core.AWSClientFactory;
import com.amazonaws.eclipse.core.AwsToolkitCore;
import com.amazonaws.eclipse.core.regions.Region;
import com.amazonaws.eclipse.core.regions.RegionUtils;
import com.amazonaws.eclipse.core.regions.ServiceAbbreviations;
import com.amazonaws.eclipse.elasticbeanstalk.resources.BeanstalkResourceProvider;
import com.amazonaws.eclipse.elasticbeanstalk.solutionstacks.SolutionStacks;
import com.amazonaws.eclipse.elasticbeanstalk.util.ElasticBeanstalkClientExtensions;
import com.amazonaws.eclipse.elasticbeanstalk.util.BeanstalkConstants;
import com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalk;
import com.amazonaws.services.elasticbeanstalk.model.ApplicationVersionDescription;
import com.amazonaws.services.elasticbeanstalk.model.ConfigurationOptionSetting;
import com.amazonaws.services.elasticbeanstalk.model.CreateApplicationRequest;
import com.amazonaws.services.elasticbeanstalk.model.CreateApplicationVersionRequest;
import com.amazonaws.services.elasticbeanstalk.model.CreateEnvironmentRequest;
import com.amazonaws.services.elasticbeanstalk.model.DescribeEventsRequest;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentDescription;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentHealth;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentStatus;
import com.amazonaws.services.elasticbeanstalk.model.EnvironmentTier;
import com.amazonaws.services.elasticbeanstalk.model.EventDescription;
import com.amazonaws.services.elasticbeanstalk.model.S3Location;
import com.amazonaws.services.elasticbeanstalk.model.UpdateEnvironmentRequest;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.model.AddRoleToInstanceProfileRequest;
import com.amazonaws.services.identitymanagement.model.CreateInstanceProfileRequest;
import com.amazonaws.services.identitymanagement.model.CreateRoleRequest;
import com.amazonaws.services.identitymanagement.model.GetInstanceProfileRequest;
import com.amazonaws.services.identitymanagement.model.GetRoleRequest;
import com.amazonaws.services.identitymanagement.model.InstanceProfile;
import com.amazonaws.services.identitymanagement.model.PutRolePolicyRequest;
import com.amazonaws.services.identitymanagement.model.Role;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.util.StringUtils;
public class ElasticBeanstalkPublishingUtils {
/** Duration (in milliseconds) before we give up polling for deployment status */
private static final int POLLING_TIMEOUT = 1000 * 60 * 20;
/** Period (in milliseconds) between attempts to poll */
private static final int PAUSE = 1000 * 15;
private final BeanstalkResourceProvider resourceProvider = new BeanstalkResourceProvider();
private final AWSElasticBeanstalk beanstalkClient;
private final ElasticBeanstalkClientExtensions beanstalkClientExtensions;
private final AmazonS3 s3;
private final Environment environment;
private final AmazonIdentityManagement iam;
public ElasticBeanstalkPublishingUtils(Environment environment) {
this.environment = environment;
AWSClientFactory clientFactory = AwsToolkitCore.getClientFactory(environment.getAccountId());
Region environmentRegion = RegionUtils.getRegionByEndpoint(environment.getRegionEndpoint());
this.beanstalkClient = clientFactory.getElasticBeanstalkClientByEndpoint(environment.getRegionEndpoint());
this.beanstalkClientExtensions = new ElasticBeanstalkClientExtensions(beanstalkClient);
this.iam = clientFactory.getIAMClientByEndpoint(environmentRegion.getServiceEndpoint(ServiceAbbreviations.IAM));
this.s3 = clientFactory.getS3ClientByEndpoint(environmentRegion.getServiceEndpoint(ServiceAbbreviations.S3));
}
public void publishApplicationToElasticBeanstalk(IPath war, String versionLabel, IProgressMonitor monitor)
throws CoreException {
trace("Publishing application to AWS Elastic Beanstalk");
monitor.beginTask("Deploying application with AWS Elastic Beanstalk", 100);
String bucketName;
String applicationName = environment.getApplicationName();
String environmentName = environment.getEnvironmentName();
String key = formVersionKey(applicationName, versionLabel);
checkForCancellation(monitor);
long deployStartTime = System.currentTimeMillis();
try {
bucketName = beanstalkClient.createStorageLocation().getS3Bucket();
if (s3.doesBucketExist(bucketName) == false) {
trace("Creating Amazon S3 bucket");
monitor.setTaskName("Creating Amazon S3 bucket");
s3.createBucket(bucketName);
checkForCancellation(monitor);
}
trace("Uploading application to Amazon S3");
monitor.setTaskName("Uploading application to Amazon S3");
long startTime = System.currentTimeMillis();
s3.putObject(bucketName, key, war.toFile());
long endTime = System.currentTimeMillis();
ElasticBeanstalkAnalytics.trackUploadMetrics(endTime - startTime, war.toFile().length());
checkForCancellation(monitor);
monitor.worked(40);
} catch (AmazonClientException ace) {
throw new CoreException(new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to upload application to Amazon S3: " + ace.getMessage(), ace));
}
try {
trace("Registering new application version from " + war.toOSString());
monitor.setTaskName("Registering application version " + versionLabel);
beanstalkClient.createApplicationVersion(new CreateApplicationVersionRequest()
.withApplicationName(applicationName).withAutoCreateApplication(true)
.withDescription(environment.getApplicationDescription()).withVersionLabel(versionLabel)
.withSourceBundle(new S3Location().withS3Bucket(bucketName).withS3Key(key)));
checkForCancellation(monitor);
monitor.worked(40);
} catch (AmazonClientException ace) {
throw new CoreException(new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to register application version with AWS Elastic Beanstalk: " + ace.getMessage(), ace));
}
trace("Updating environment");
monitor.setTaskName("Updating environment with latest version");
if (beanstalkClientExtensions.doesEnvironmentExist(environmentName)) {
try {
beanstalkClient.updateEnvironment(new UpdateEnvironmentRequest().withEnvironmentName(environmentName)
.withVersionLabel(versionLabel));
} catch (AmazonClientException ace) {
throw new CoreException(new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to update environment with new application version: " + ace.getMessage(), ace));
}
} else {
try {
createNewEnvironment(versionLabel);
} catch (AmazonClientException ace) {
throw new CoreException(new Status(IStatus.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to create new environment: " + ace.getMessage(), ace));
}
}
ElasticBeanstalkAnalytics.trackDeployTotalTime(System.currentTimeMillis() - deployStartTime);
trace("Done publishing to AWS Elastic Beanstalk, waiting for env to become available...");
checkForCancellation(monitor);
monitor.worked(20);
monitor.done();
}
/**
* Creates a new Elastic Beanstalk application, after checking to make sure it doesn't already
* exist.
*
* @param applicationName
* The name of the application to create.
* @param description
* An optional description for the new environment.
*/
public void createNewApplication(String applicationName, String description) {
if (beanstalkClientExtensions.doesApplicationExist(applicationName)) {
beanstalkClient.createApplication(new CreateApplicationRequest(applicationName)
.withDescription(description));
}
}
/**
* Returns the version label for the latest version registered for the specified application.
*
* @param applicationName
* The name of the application whose latest version should be returned.
* @return The label of the latest version registered for the specified application, or null if
* no versions are registered.
* @throws AmazonServiceException
* If the specified application doesn't exist.
*/
public String getLatestApplicationVersion(String applicationName) {
ApplicationVersionDescription applicationVersion = beanstalkClientExtensions
.getLatestApplicationVersionDescription(applicationName);
if (applicationVersion == null) {
return null;
}
return applicationVersion.getVersionLabel();
}
private static final Map<String, String> ENV_TIER_MAP;
static {
Map<String, String> map = new HashMap<String, String>();
map.put(ConfigurationOptionConstants.WEB_SERVER, "Standard");
map.put(ConfigurationOptionConstants.WORKER, "SQS/HTTP");
ENV_TIER_MAP = Collections.unmodifiableMap(map);
}
private static final Map<String, String> ENV_TYPE_MAP;
static {
Map<String, String> map = new HashMap<String, String>();
map.put(ConfigurationOptionConstants.SINGLE_INSTANCE_ENV, "SingleInstance");
map.put(ConfigurationOptionConstants.LOAD_BALANCED_ENV, "LoadBalanced");
ENV_TYPE_MAP = Collections.unmodifiableMap(map);
}
/**
* Creates a new environment, using the specified version as the initial version to deploy.
*
* @param versionLabel
* The initial version to deploy to the new environment.
*/
public void createNewEnvironment(String versionLabel) {
String solutionStackName = environment.getSolutionStack();
if (solutionStackName == null) {
solutionStackName = SolutionStacks.getDefaultSolutionStackName();
}
CreateEnvironmentRequest request = new CreateEnvironmentRequest()
.withApplicationName(environment.getApplicationName()).withSolutionStackName(solutionStackName)
.withDescription(environment.getEnvironmentDescription())
.withEnvironmentName(environment.getEnvironmentName()).withVersionLabel(versionLabel);
List<ConfigurationOptionSetting> optionSettings = new ArrayList<ConfigurationOptionSetting>();
if (!StringUtils.isNullOrEmpty(environment.getKeyPairName())) {
optionSettings.add(new ConfigurationOptionSetting().withNamespace(ConfigurationOptionConstants.LAUNCHCONFIGURATION)
.withOptionName("EC2KeyName").withValue(environment.getKeyPairName()));
}
if (!StringUtils.isNullOrEmpty(environment.getHealthCheckUrl())) {
optionSettings.add(new ConfigurationOptionSetting().withNamespace(ConfigurationOptionConstants.APPLICATION)
.withOptionName("Application Healthcheck URL").withValue(environment.getHealthCheckUrl()));
}
if (!StringUtils.isNullOrEmpty(environment.getSslCertificateId())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.LOADBALANCER).withOptionName("SSLCertificateId")
.withValue(environment.getSslCertificateId()));
}
if (!StringUtils.isNullOrEmpty(environment.getSnsEndpoint())) {
optionSettings.add(new ConfigurationOptionSetting().withNamespace(ConfigurationOptionConstants.SNS_TOPICS)
.withOptionName("Notification Endpoint").withValue(environment.getSnsEndpoint()));
}
if (!StringUtils.isNullOrEmpty(environment.getEnvironmentTier())) {
request.setTier(new EnvironmentTier().withName(environment.getEnvironmentTier())
.withType(ENV_TIER_MAP.get(environment.getEnvironmentTier())).withVersion("1.0"));
}
if (!StringUtils.isNullOrEmpty(environment.getEnvironmentType())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.ENVIRONMENT_TYPE).withOptionName("EnvironmentType")
.withValue(ENV_TYPE_MAP.get(environment.getEnvironmentType())));
}
if (!StringUtils.isNullOrEmpty(environment.getInstanceRoleName())) {
if (!environment.isSkipIamRoleAndInstanceProfileCreation()) {
// Create the role/instance-profile if necessary
tryConfigureRoleAndInstanceProfile();
}
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.LAUNCHCONFIGURATION)
.withOptionName("IamInstanceProfile").withValue(environment.getInstanceRoleName()));
}
if (!StringUtils.isNullOrEmpty(environment.getServiceRoleName())) {
if (!environment.isSkipIamRoleAndInstanceProfileCreation()
&& environment.getServiceRoleName().equals(BeanstalkConstants.DEFAULT_SERVICE_ROLE_NAME)) {
tryCreateDefaultServiceRoleIfNotExists();
}
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.ENVIRONMENT_TYPE).withOptionName("ServiceRole")
.withValue(environment.getServiceRoleName()));
if (doesSolutionStackSupportEnhancedHealth(solutionStackName)) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.HEALTH_REPORTING_SYSTEM)
.withOptionName("SystemType").withValue("enhanced"));
}
}
if (!StringUtils.isNullOrEmpty(environment.getVpcId())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.VPC)
.withOptionName("VPCId")
.withValue(environment.getVpcId()));
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.VPC)
.withOptionName("AssociatePublicIpAddress")
.withValue(String.valueOf(environment.getAssociatePublicIpAddress())));
if (!StringUtils.isNullOrEmpty(environment.getSubnets())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.VPC)
.withOptionName("Subnets")
.withValue(environment.getSubnets()));
}
if (!StringUtils.isNullOrEmpty(environment.getElbSubnets())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.VPC)
.withOptionName("ELBSubnets")
.withValue(environment.getElbSubnets()));
}
if (!StringUtils.isNullOrEmpty(environment.getElbScheme())
&& BeanstalkConstants.ELB_SCHEME_INTERNAL.equals(environment.getElbScheme())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.VPC)
.withOptionName("ELBScheme")
.withValue(environment.getElbScheme()));
}
if (!StringUtils.isNullOrEmpty(environment.getSecurityGroup())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.LAUNCHCONFIGURATION)
.withOptionName("SecurityGroups")
.withValue(environment.getSecurityGroup()));
}
}
if (StringUtils.isNullOrEmpty(environment.getWorkerQueueUrl())) {
optionSettings.add(new ConfigurationOptionSetting()
.withNamespace(ConfigurationOptionConstants.SQSD)
.withOptionName("WorkerQueueURL")
.withValue(environment.getWorkerQueueUrl()));
}
if (optionSettings.size() > 0) {
request.setOptionSettings(optionSettings);
}
if (!StringUtils.isNullOrEmpty(environment.getCname())) {
request.setCNAMEPrefix(environment.getCname());
}
beanstalkClient.createEnvironment(request);
}
private boolean doesSolutionStackSupportEnhancedHealth(String solutionStackName) {
return !solutionStackName.contains("Tomcat 6");
}
private void tryCreateDefaultServiceRoleIfNotExists() {
try {
String permissionsPolicy = resourceProvider.getServiceRolePermissionsPolicy().asString();
String trustPolicy = resourceProvider.getServiceRoleTrustPolicy().asString();
createRoleIfNotExists(BeanstalkConstants.DEFAULT_SERVICE_ROLE_NAME, permissionsPolicy, trustPolicy);
} catch (Exception e) {
Status status = new Status(Status.WARNING, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to create default service role. "
+ "Proceeding with deployment under the assumption it already exists", e);
StatusManager.getManager().handle(status, StatusManager.LOG);
}
}
private void createRoleIfNotExists(String roleName, String permissionsPolicy, String trustPolicy) {
if (!doesRoleExist(roleName)) {
iam.createRole(new CreateRoleRequest().withRoleName(roleName).withPath("/")
.withAssumeRolePolicyDocument(trustPolicy));
iam.putRolePolicy(new PutRolePolicyRequest().withRoleName(roleName)
.withPolicyName("DefaultAccessPolicy-" + roleName).withPolicyDocument(permissionsPolicy));
}
}
private boolean doesRoleExist(String roleName) {
return getRole(BeanstalkConstants.DEFAULT_SERVICE_ROLE_NAME) != null;
}
private void tryConfigureRoleAndInstanceProfile() {
try {
configureRoleAndInstanceProfile();
} catch (Exception e) {
Status status = new Status(Status.WARNING, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to create default instance role or instance profile. "
+ "Proceeding with deployment under the assumption they already exist.", e);
StatusManager.getManager().handle(status, StatusManager.LOG);
}
}
private void configureRoleAndInstanceProfile() {
String roleName = environment.getInstanceRoleName();
if (BeanstalkConstants.DEFAULT_INSTANCE_ROLE_NAME.equals(roleName)) {
String permissionsPolicy = resourceProvider.getInstanceProfilePermissionsPolicy().asString();
String trustPolicy = resourceProvider.getInstanceProfileTrustPolicy().asString();
createRoleIfNotExists(BeanstalkConstants.DEFAULT_INSTANCE_ROLE_NAME, permissionsPolicy, trustPolicy);
}
String instanceProfileName = roleName;
// The console automatically creates an instance profile with the same name when you create
// an EC2 IAM role. If no instance profile exists then the user most likely created the role
// through the API so we create the instance profile on their behalf
InstanceProfile instanceProfile = createInstanceProfileIfNotExists(instanceProfileName);
// If an instance profile that has the same name as the role exists but doesn't have that
// role attached then add it here. This can really only happen if the user is creating the
// role and instance profile separately through the
// API
if (!isRoleAddedToInstanceProfile(roleName, instanceProfile)) {
iam.addRoleToInstanceProfile(new AddRoleToInstanceProfileRequest().withInstanceProfileName(
instanceProfileName).withRoleName(roleName));
}
}
/**
* Create the instance profile with the specified name or return it if it already exists.
*
* @param instanceProfileName
* @return InstanceProfile object of either the existing instance profile or the newly created
* one
*/
private InstanceProfile createInstanceProfileIfNotExists(String instanceProfileName) {
InstanceProfile instanceProfile = getInstanceProfile(instanceProfileName);
if (instanceProfile == null) {
instanceProfile = iam.createInstanceProfile(
new CreateInstanceProfileRequest().withInstanceProfileName(instanceProfileName).withPath("/"))
.getInstanceProfile();
}
return instanceProfile;
}
private InstanceProfile getInstanceProfile(String profileName) throws AmazonClientException {
try {
return iam.getInstanceProfile(new GetInstanceProfileRequest().withInstanceProfileName(profileName))
.getInstanceProfile();
} catch (AmazonServiceException ase) {
if (ase.getErrorCode().equals("NoSuchEntity")) {
return null;
}
throw ase;
}
}
private Role getRole(String roleName) throws AmazonClientException {
try {
return iam.getRole(new GetRoleRequest().withRoleName(roleName)).getRole();
} catch (AmazonServiceException ase) {
if (ase.getErrorCode().equals("NoSuchEntity")) {
return null;
}
throw ase;
}
}
private boolean isRoleAddedToInstanceProfile(String roleName, InstanceProfile instanceProfile) {
for (Role role : instanceProfile.getRoles()) {
if (role.getRoleName().equals(roleName)) {
return true;
}
}
return false;
}
public void waitForEnvironmentToBecomeAvailable(IModule moduleToPublish, IProgressMonitor monitor, Runnable runnable)
throws CoreException {
int errorCount = 0;
long startTime = System.currentTimeMillis();
Date eventStartTime = new Date(startTime - (1000 * 60 * 30));
String applicationName = environment.getApplicationName();
String environmentName = environment.getEnvironmentName();
boolean launchingNewEnvironment = isLaunchingNewEnvironment(environmentName);
monitor.beginTask("Waiting for environment to become available", POLLING_TIMEOUT);
monitor.setTaskName("Waiting for environment to become available");
while (System.currentTimeMillis() - startTime < POLLING_TIMEOUT) {
List<EventDescription> events = beanstalkClient.describeEvents(
new DescribeEventsRequest().withEnvironmentName(environmentName).withStartTime(eventStartTime))
.getEvents();
if (events.size() > 0) {
String status = "Latest Event: " + events.get(0).getMessage();
if (launchingNewEnvironment) {
status += " (Note: Launching a new environment may take several minutes)";
} else {
status += " (Note: Updating an environment may take several minutes)";
}
monitor.setTaskName(status);
}
try {
Thread.sleep(PAUSE);
} catch (Exception e) {
}
if (monitor.isCanceled()) {
return;
}
if (runnable != null) {
try {
runnable.run();
} catch (Exception e) {
Status status = new Status(Status.INFO, ElasticBeanstalkPlugin.PLUGIN_ID, e.getMessage(), e);
StatusManager.getManager().handle(status, StatusManager.LOG);
}
}
try {
trace("Polling environment for status...");
EnvironmentDescription environmentDesc = beanstalkClientExtensions
.getEnvironmentDescription(environmentName);
if (environmentDesc != null) {
trace(" - " + environmentDesc.getStatus());
EnvironmentStatus environmentStatus = null;
try {
environmentStatus = EnvironmentStatus.fromValue(environmentDesc.getStatus());
} catch (IllegalArgumentException e) {
Status status = new Status(Status.INFO, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unknown environment status: " + environmentDesc.getStatus());
StatusManager.getManager().handle(status, StatusManager.LOG);
continue;
}
switch (environmentStatus) {
case Ready:
trace(" - Health: " + environmentDesc.getHealth());
if (EnvironmentHealth.Green.toString().equalsIgnoreCase(environmentDesc.getHealth())) {
trace("**Server started**");
Status status = new Status(Status.INFO, ElasticBeanstalkPlugin.PLUGIN_ID,
"Deployed application '" + applicationName + "' " + "to environment '"
+ environmentName + "' " + "\nApplication available at: "
+ environmentDesc.getCNAME());
StatusManager.getManager().handle(status, StatusManager.LOG);
return;
}
break;
case Terminated:
case Terminating:
throw new CoreException(new Status(Status.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Environment failed to deploy. Check environment events for more details."));
}
}
// reset error count so that we only count consecutive errors
errorCount = 0;
} catch (AmazonClientException ace) {
if (errorCount++ > 4) {
throw new CoreException(new Status(Status.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to detect application deployment: " + ace.getMessage(), ace));
}
}
}
throw new CoreException(new Status(Status.ERROR, ElasticBeanstalkPlugin.PLUGIN_ID,
"Unable to detect application deployment"));
}
private void checkForCancellation(IProgressMonitor monitor) throws CoreException {
if (monitor.isCanceled()) {
throw new CoreException(new Status(Status.CANCEL, ElasticBeanstalkPlugin.PLUGIN_ID, "Canceled"));
}
}
private boolean isLaunchingNewEnvironment(String environmentName) {
EnvironmentDescription environmentDesc = beanstalkClientExtensions.getEnvironmentDescription(environmentName);
if (environmentDesc == null) {
return true;
}
return environmentDesc.getStatus().equals(EnvironmentStatus.Launching.toString());
}
/**
* Returns the key under which to store an uploaded application version.
*/
private String formVersionKey(String applicationName, String versionLabel) {
try {
return URLEncoder.encode(applicationName + "-" + versionLabel + ".war", "UTF-8");
} catch (UnsupportedEncodingException e) {
return applicationName + "-" + versionLabel + ".war";
}
}
}