Java tutorial
/** * Copyright (c) 2011, Pykl Studios <admin@pykl.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.tracermedia.maven.plugins; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.TimeZone; import com.amazonaws.services.elasticbeanstalk.model.ApplicationVersionDescription; import com.amazonaws.services.elasticbeanstalk.model.CreateApplicationVersionRequest; import com.amazonaws.services.elasticbeanstalk.model.CreateApplicationVersionResult; import com.amazonaws.services.elasticbeanstalk.model.DescribeApplicationVersionsResult; import com.amazonaws.services.elasticbeanstalk.model.S3Location; import com.amazonaws.services.elasticbeanstalk.model.UpdateEnvironmentRequest; import com.amazonaws.services.elasticbeanstalk.model.UpdateEnvironmentResult; import com.amazonaws.services.s3.internal.Mimetypes; import com.amazonaws.services.s3.internal.ProgressReportingInputStream; import com.amazonaws.services.s3.internal.RepeatableFileInputStream; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.ProgressEvent; import com.amazonaws.services.s3.model.ProgressListener; import com.amazonaws.services.s3.model.PutObjectRequest; import org.apache.maven.model.Build; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; /** * Deploys a new version of the application to the Amazon Elastic Beanstalk service. * * @goal create-version */ public class CreateVersionMojo extends AbstractBeanstalkMojo { protected static final DateFormat DF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); /** * The name of the application version to deploy. If the specified application has no associated * application versions, If not specified, AWS Elastic Beanstalk attempts to launch the most * recently created application version. * * @parameter expression="${versionLabel}" */ protected String versionLabel; /** * The Amazon S3 bucket that identify the location of the source bundle for this version. * If not specified, AWS Elastic Beanstalk uses a sample application. * * @parameter expression="${s3Bucket}" */ protected String s3Bucket; /** * The name of the environment to update. * * @parameter expression="${environmentName}" * @required */ protected String environmentName; /** * The Amazon S3 key that identify the location of the source bundle for this version. * If not specified, a key is generated using the application name and a timestamp. * * @parameter expression="${s3Key}" */ protected String s3Key; /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; public CreateVersionMojo() { DF.setTimeZone(TimeZone.getTimeZone("GMT")); } public void execute() throws MojoExecutionException, MojoFailureException { final Date now = new Date(); if (!project.getPackaging().equalsIgnoreCase("war") && !project.getPackaging().equalsIgnoreCase("uberwar")) { throw new MojoExecutionException( "Only WAR projects can be deployed to Amazon Beanstalk. Not " + project.getPackaging()); } System.out.println("Existing versions:"); for (ApplicationVersionDescription version : getVersions()) { if (version.getApplicationName().equals(applicationName)) { System.out.println(String.format("App Name: %25s, version: %20s, S3: %s/%s", version.getApplicationName(), version.getVersionLabel(), version.getSourceBundle().getS3Bucket(), version.getSourceBundle().getS3Key())); } } final Build build = project.getBuild(); // It would be much better to use project.getPackaging() instead of hardcoding "war". But // the Mojo we use to combine multiple WAR files has a package of 'uberwar'. String artifactPath = String.format("%s/%s.%s", build.getDirectory(), build.getFinalName(), "war"); // Need to push the artifact to S3. Place in the s3Bucket using the s3Key. If the key is // not specified, it is generated by using the applicationName and appending a timestamp. if (s3Key == null) { s3Key = applicationName + '-' + DF.format(now); } try { copyFileToS3(s3Bucket, s3Key, new File(artifactPath)); } catch (IOException e) { throw new MojoFailureException("Failed to copy file to Amazon S3", e); } // If a version label has not been set, we will use the applicationKey and timestamp. if (versionLabel == null) { versionLabel = applicationName + '-' + DF.format(now); } // Create the new version of the application. createApplicationVersion(applicationName, versionLabel, s3Bucket, s3Key); updateEnvironmentVersion(environmentName, versionLabel); } protected List<ApplicationVersionDescription> getVersions() { final DescribeApplicationVersionsResult versionsResult = getBeanstalkClient().describeApplicationVersions(); return versionsResult.getApplicationVersions(); } protected void createApplicationVersion(String applicationName, String versionLabel, String s3Bucket, String s3Key) { final CreateApplicationVersionRequest versionRequest = new CreateApplicationVersionRequest(applicationName, versionLabel); if (s3Bucket != null && s3Key != null) { final S3Location location = new S3Location(s3Bucket, s3Key); versionRequest.setSourceBundle(location); } else { System.err.println("Warning: Deploying sample application because S3 location " + "is not specified. (Hint: s3Bucket, s3Key)."); } final CreateApplicationVersionResult versionResult = getBeanstalkClient() .createApplicationVersion(versionRequest); System.out.println(String.format("Deployed application [%s/%s] to Amazon Beanstalk.", versionResult.getApplicationVersion().getApplicationName(), versionResult.getApplicationVersion().getVersionLabel())); } protected void updateEnvironmentVersion(String environmentName, String versionLabel) { final UpdateEnvironmentRequest envRequest = new UpdateEnvironmentRequest() .withEnvironmentName(environmentName).withVersionLabel(versionLabel); final UpdateEnvironmentResult envResult = getBeanstalkClient().updateEnvironment(envRequest); System.out.println(String.format( "Updated environment [%s] with new version of %s (%s). Health: %s, status: %s, Endpoint: %s", envResult.getEnvironmentName(), envResult.getApplicationName(), versionLabel, envResult.getHealth(), envResult.getStatus(), envResult.getEndpointURL())); } protected void copyFileToS3(final String s3Bucket, final String s3Key, final File file) throws IOException { final ObjectMetadata meta = new ObjectMetadata(); InputStream in = new FileInputStream(file); try { meta.setContentLength(file.length()); meta.setContentType(Mimetypes.getInstance().getMimetype(file)); } finally { in.close(); } in = new ProgressReportingInputStream(new RepeatableFileInputStream(file), new ProgressListener() { int lastPercent = -1; int bytes = 0; public void progressChanged(ProgressEvent progressEvent) { bytes += progressEvent.getBytesTransfered(); double percent = 100.0 * bytes / meta.getContentLength(); if ((int) percent != lastPercent) { System.out.print( String.format("\rCopying file [%s] to S3, bucket: %s, key: %s, progress: %.0f%% ", file.getName(), s3Bucket, s3Key, percent)); lastPercent = (int) percent; } } }); try { final PutObjectRequest request = new PutObjectRequest(s3Bucket, s3Key, in, meta); getS3Client().putObject(request); System.out.println(String.format("\rCopying file [%s] to S3, bucket: %s, key: %s, progress: %.0f%% ", file.getName(), s3Bucket, s3Key, 100.0)); } finally { in.close(); } } }