View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.aws.cloudfront;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.InputStream;
20  import java.text.SimpleDateFormat;
21  import java.util.List;
22  import java.util.TimeZone;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.kuali.common.aws.AmazonWebServiceRequestType;
26  import org.kuali.common.aws.TypedRequest;
27  import org.kuali.common.aws.s3.old.BucketContext;
28  import org.kuali.common.util.Str;
29  
30  import com.amazonaws.services.s3.model.CopyObjectRequest;
31  import com.amazonaws.services.s3.model.ObjectListing;
32  import com.amazonaws.services.s3.model.ObjectMetadata;
33  import com.amazonaws.services.s3.model.PutObjectRequest;
34  import com.amazonaws.services.s3.model.S3ObjectSummary;
35  
36  public class CloudFrontUtils {
37  
38  	private static final String INDEX_METADATA_KEY = "maven-cloudfront-plugin-index";
39  	private static final String INDEX_CONTENT_TYPE = "text/html";
40  
41  	/**
42  	 * Return a date formatter for the indicated format and timezone.
43  	 */
44  	public static SimpleDateFormat getSimpleDateFormat(String format, String timezone) {
45  		SimpleDateFormat sdf = new SimpleDateFormat(format);
46  		sdf.setTimeZone(TimeZone.getTimeZone(timezone));
47  		return sdf;
48  	}
49  
50  	/**
51  	 * An <code>ObjectListing</code> is the equivalent of typing <code>ls</code> in a directory on a file system.
52  	 */
53  	public static String getFirstMatchingKey(ObjectListing listing, List<String> filenames) {
54  		// Cycle through the list of files in this directory
55  		for (S3ObjectSummary summary : listing.getObjectSummaries()) {
56  			String objectKey = getFirstMatchingKey(summary.getKey(), listing.getPrefix(), filenames);
57  			if (objectKey != null) {
58  				return objectKey;
59  			}
60  		}
61  		return null;
62  	}
63  
64  	public static String getFirstMatchingKey(String objectKey, String prefix, List<String> filenames) {
65  		// Cycle through the list of filenames
66  		for (String filename : filenames) {
67  			// Append the file name to the key for this directory
68  			String completeKey = prefix + filename;
69  			// We found a filename in this directory that matches what we are looking for
70  			if (StringUtils.equals(objectKey, completeKey)) {
71  				return completeKey;
72  			}
73  		}
74  		return null;
75  	}
76  
77  	/**
78  	 * Create a CopyObjectRequest with an ACL set to PublicRead
79  	 */
80  	public static CopyObjectRequest getCopyObjectRequest(String bucket, String src, String dst) {
81  		CopyObjectRequest request = new CopyObjectRequest(bucket, src, bucket, dst);
82  		request.setCannedAccessControlList(CloudFrontConstants.DEFAULT_ACL);
83  		return request;
84  	}
85  
86  	/**
87  	 * Create a PutObjectRequest from the html. The PutObjectRequest sets the content type to <code>text/html</code>, sets the ACL to <code>PublicRead</code>, and adds the metadata
88  	 * <code>maven-cloudfront-plugin-index=true</code>
89  	 */
90  	public static PutObjectRequest getPutHtmlRequest(String bucket, String cacheControl, String html, String key) {
91  
92  		// Setup an InputStream that reads from the HTML string
93  		InputStream in = new ByteArrayInputStream(html.getBytes());
94  
95  		// Create some metadata for identifying this S3 object as an index
96  		ObjectMetadata om = new ObjectMetadata();
97  		om.setCacheControl(cacheControl);
98  		om.setContentType(INDEX_CONTENT_TYPE);
99  		om.setContentLength(html.length());
100 		om.addUserMetadata(INDEX_METADATA_KEY, "true");
101 
102 		// Create a request object
103 		PutObjectRequest request = new PutObjectRequest(bucket, key, in, om);
104 		request.setCannedAcl(CloudFrontConstants.DEFAULT_ACL);
105 		return request;
106 	}
107 
108 	public static TypedRequest getTypedRequestWithoutTrailingDelimiter(BucketContext context, String cacheControl, ObjectListing listing, String html) {
109 		// Create s3://bucket/foo/bar
110 		PutObjectRequest index = getPutHtmlRequestWithoutTrailingDelimiter(context, cacheControl, listing, html);
111 		return new TypedRequest(index, AmazonWebServiceRequestType.PUT_OBJECT);
112 	}
113 
114 	/**
115 	 * This does one of two things. It either copies <code>/foo/bar/index.html to /foo/bar/</code> OR creates <code>/foo/bar/</code> from <code>html</code>
116 	 */
117 	public static TypedRequest getTypedRequest(String bucket, String cacheControl, String welcomeFileKey, ObjectListing listing, String html) {
118 		if (welcomeFileKey == null) {
119 			// Create s3://bucket/foo/bar/
120 			PutObjectRequest put = getPutHtmlRequest(bucket, cacheControl, html, listing.getPrefix());
121 			return new TypedRequest(put, AmazonWebServiceRequestType.PUT_OBJECT);
122 		} else {
123 			// Copy s3://bucket/foo/bar/index.html -> s3://bucket/foo/bar/
124 			CopyObjectRequest copy = getCopyObjectRequest(bucket, welcomeFileKey, listing.getPrefix());
125 			return new TypedRequest(copy, AmazonWebServiceRequestType.COPY_OBJECT);
126 		}
127 	}
128 
129 	public static PutObjectRequest getPutHtmlRequestWithoutTrailingDelimiter(BucketContext context, String cacheControl, ObjectListing listing, String html) {
130 		String delimiter = context.getDelimiter();
131 		String objectKey = Str.removeSuffix(listing.getPrefix(), delimiter);
132 		return getPutHtmlRequest(context.getName(), cacheControl, html, objectKey);
133 	}
134 
135 	public static PutObjectRequest getPutHtmlRequest(BucketContext context, String cacheControl, ObjectListing listing, String html) {
136 		return getPutHtmlRequest(context.getName(), cacheControl, html, listing.getPrefix());
137 	}
138 }