Java tutorial
/* * #%L * BroadleafCommerce Amazon Integrations * %% * Copyright (C) 2009 - 2014 Broadleaf Commerce * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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. * #L% */ package org.broadleafcommerce.vendor.amazon.s3; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.broadleafcommerce.common.file.domain.FileWorkArea; import org.broadleafcommerce.common.file.service.BroadleafFileServiceExtensionManager; import org.broadleafcommerce.common.file.service.BroadleafFileServiceImpl; import org.broadleafcommerce.common.site.domain.SiteImpl; import org.broadleafcommerce.common.web.BroadleafRequestContext; import org.junit.BeforeClass; import org.junit.Test; import com.amazonaws.regions.RegionUtils; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.S3Object; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.Scanner; /** * This test will connect to AmazonS3, create a bucket, create a file, delete the file, and delete the bucket. * * This test requires an S3 keys and S3 accessId which can be passed in as -D arguments or stored * in a property file in your classpath named. * * "/config/bc/override/common.properties." * @author bpolster * */ public class S3FileServiceProviderTest extends AbstractS3Test { private static S3FileServiceProvider s3FileProvider = new S3FileServiceProvider(); private static final String TEST_FILE_CONTENTS = "abcdefghijklmnopqrstuvwxyz\n" + "01234567890112345678901234\n" + "!@#$%^&*()-=[]{};':',.<>/?\n" + "01234567890112345678901234\n" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public class S3BroadleafFileService extends BroadleafFileServiceImpl { public S3BroadleafFileService() { extensionManager = new BroadleafFileServiceExtensionManager(); } } @BeforeClass public static void setupProvider() { s3FileProvider.s3ConfigurationService = configService; s3FileProvider.setBroadleafFileService(new S3FileServiceProviderTest().new S3BroadleafFileService()); } @Test public void testFileProcesses() throws IOException { resetAllProperties(); //AbstractS3Test.propService.setProperty("aws.s3.bucketSubDirectory", "img"); String filename = "blcTestFile.txt"; boolean ok = uploadTestFileTestOk(filename); assertTrue("File added to s3 with no exception.", ok); ok = checkTestFileExists(filename); assertTrue("File retrieved from s3 with no exception.", ok); ok = deleteTestFile(filename); // The file should not exist on S3 ok = !checkTestFileExists(filename); assertTrue("File removed from s3 with no exception.", ok); } @Test public void testSubDirectory() throws IOException { resetAllProperties(); String filename = "blcTestFile.txt"; String subDirectory = "img"; verifyFileUploadRaw(filename, subDirectory); } @Test public void testSubDirectoryWithSlashes() throws IOException { resetAllProperties(); String filename = "/blcTestFile.txt"; String subDirectory = "/img/"; verifyFileUploadRaw(filename, subDirectory); } @Test public void testSiteSpecificFile() throws IOException { // initialize the site before resetting properties to get the properties cache right BroadleafRequestContext context = new BroadleafRequestContext(); SiteImpl site = new SiteImpl(); site.setId(10l); site.setName("Test Site"); context.setNonPersistentSite(site); BroadleafRequestContext.setBroadleafRequestContext(context); resetAllProperties(); String filename = "/blcTestFile.txt"; String subDirectory = "/img/"; verifyFileUploadRaw(filename, subDirectory); BroadleafRequestContext.setBroadleafRequestContext(new BroadleafRequestContext()); } @Test public void testRemoveAddedResourceByName() { resetAllProperties(); String fileName = "blcTestFile.txt"; propService.setProperty("aws.s3.bucketSubDirectory", "/img/"); List<String> resourceNames = uploadTestFileWithResult(fileName); assertTrue("No resource names return", CollectionUtils.isNotEmpty(resourceNames)); assertTrue("More than 1 resource returned when only uploading a single resource", resourceNames.size() == 1); assertTrue(s3FileProvider.removeResource(resourceNames.get(0))); } @Test public void testNotFoundReturnsNonExistentFile() { resetAllProperties(); File file = s3FileProvider.getResource("blahblahgarbledygoopcannotfind.ext"); assertTrue("The returned file should not exist", !file.exists()); } @Test public void testSubDirectoryTree() throws IOException { resetAllProperties(); String filename = "/blcTestFile.txt"; String subDirectory = "/img/sub1/sub2"; verifyFileUploadRaw(filename, subDirectory); } /** * Differs from {@link #checkTestFileExists(String)} in that this uses the S3 client directly and does * not go through the Broadleaf file service API. This will create a test file, upload it to S3 via the * Broadleaf file service API, verify that the file exists via the raw S3 client, and then delete the file * from the bucket via the file service API again * * @param filename the name of the file to upload * @param directoryName directory that the file should be stored in on S3 */ protected void verifyFileUploadRaw(String filename, String directoryName) throws IOException { propService.setProperty("aws.s3.bucketSubDirectory", directoryName); boolean ok = uploadTestFileTestOk(filename); assertTrue("File added to s3 with no exception.", ok); // Use the S3 client directly to ensure that it was uploaded to the sub-directory S3Configuration s3config = configService.lookupS3Configuration(); AmazonS3Client s3 = s3FileProvider.getAmazonS3Client(s3config); s3.setRegion(RegionUtils.getRegion(s3config.getDefaultBucketRegion())); String s3Key = s3FileProvider.getSiteSpecificResourceName(filename); if (StringUtils.isNotEmpty(directoryName)) { s3Key = directoryName + "/" + s3Key; } // Replace the starting slash and remove the double-slashes if the directory ended with a slash s3Key = s3Key.startsWith("/") ? s3Key.substring(1) : s3Key; s3Key = FilenameUtils.normalize(s3Key); S3Object object = s3.getObject(new GetObjectRequest(s3config.getDefaultBucketName(), s3Key)); InputStream inputStream = object.getObjectContent(); StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); String fileContents = writer.toString(); inputStream.close(); writer.close(); assertEquals("Retrieved the file successfully from S3", fileContents, TEST_FILE_CONTENTS); ok = deleteTestFile(filename); assertTrue("File removed from s3 with no exception.", ok); } protected boolean deleteTestFile(String filename) { boolean ok; try { s3FileProvider.removeResource(filename); ok = true; } catch (Exception e) { e.printStackTrace(); ok = false; } return ok; } protected boolean checkTestFileExists(String filename) { boolean ok = false; try { File f = s3FileProvider.getResource(filename); if (f.exists()) { Scanner fileScanner = new Scanner(f); fileScanner.useDelimiter("\\Z"); String content = fileScanner.next(); int contentLength = content.length(); if (contentLength > 10) { System.out.println("Returned file contents: " + content); ok = TEST_FILE_CONTENTS.equals(content); } fileScanner.close(); } } catch (Exception e) { ok = false; } return ok; } protected boolean uploadTestFileTestOk(String filename) { boolean ok; try { uploadTestFileWithResult(filename); ok = true; } catch (Exception e) { e.printStackTrace(); ok = false; } return ok; } protected List<String> uploadTestFileWithResult(String filename) { try { // Add the file to the amazon bucket. List<File> files = new ArrayList<File>(); File sampleFile = createSampleFile(filename); FileWorkArea workArea = new FileWorkArea(); File parentFile = sampleFile.getAbsoluteFile().getParentFile(); workArea.setFilePathLocation(parentFile.getAbsolutePath()); files.add(sampleFile); return s3FileProvider.addOrUpdateResourcesForPaths(workArea, files, false); } catch (IOException e) { return new ArrayList<String>(); } } private static File createSampleFile(String fileName) throws IOException { File file = new File(fileName.startsWith("/") ? fileName.substring(1) : fileName); file.deleteOnExit(); Writer writer = new OutputStreamWriter(new FileOutputStream(file)); writer.write(TEST_FILE_CONTENTS); writer.close(); return file; } }