Java tutorial
/* * Copyright (C) 2016 FormKiQ Inc. * * 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. */ package com.formkiq.core.service; import static com.formkiq.core.service.SystemPropertyService.ASSET_SERVICE_S3; import static com.formkiq.core.service.SystemPropertyService.S3_ACCESS_KEY; import static com.formkiq.core.service.SystemPropertyService.S3_ACCESS_SECRET; import static com.formkiq.core.service.SystemPropertyService.S3_BUCKET_NAME; import static org.springframework.util.StringUtils.isEmpty; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.transaction.Transactional; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import com.amazonaws.SdkClientException; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.Bucket; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.S3Object; import com.formkiq.core.dao.SystemDao; /** * S3 implementation of {@link AssetService}. * */ public class AssetServiceS3Default implements AssetServiceS3, InitializingBean { /** Logger. */ private static final Logger LOG = Logger.getLogger(AssetServiceS3Default.class.getName()); /** SystemDao. */ @Autowired private SystemDao systemDao; /** PlatformTransactionManager. */ @Autowired @Qualifier("transactionManager") private PlatformTransactionManager txManager; /** Whether environment supports. */ private boolean isSupported = false; /** S3 Access Key. */ private String s3AccessKey; /** S3 Access Secret. */ private String s3AccessSecret; /** S3 Bucket Name. */ private String s3BucketName; /** Amazon S3 Client. */ private AmazonS3 s3client; /** * default constructor. */ public AssetServiceS3Default() { } @Transactional @Override public void afterPropertiesSet() throws Exception { TransactionTemplate tmpl = new TransactionTemplate(this.txManager); tmpl.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(final TransactionStatus status) { reloadProperties(); } }); } @Override public void createBucket(final String name) { if (!getS3Connection().doesBucketExist(name)) { getS3Connection().createBucket(name); } } @Override public void createFolder(final String folder) { // create meta-data for your folder and set content-length to 0 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(0); // create empty content InputStream emptyContent = new ByteArrayInputStream(new byte[0]); // create a PutObjectRequest passing the folder name suffixed by / PutObjectRequest putObjectRequest = new PutObjectRequest(this.s3BucketName, folder + "/", emptyContent, metadata); // send request to S3 to create folder getS3Connection().putObject(putObjectRequest); } @Override public void deleteObject(final String folder, final String asset) { String filename = getFilename(folder, asset); getS3Connection().deleteObject(this.s3BucketName, filename); } @Override public boolean doesAssetExist(final String folder, final String asset) { String filename = getFilename(folder, asset); return getS3Connection().doesObjectExist(this.s3BucketName, filename); } @SuppressWarnings("resource") @Override public byte[] findAsset(final String folder, final String asset) throws IOException { byte[] bytes = null; String filename = getFilename(folder, asset); try { S3Object object = getS3Connection().getObject(new GetObjectRequest(this.s3BucketName, filename)); InputStream objectData = object.getObjectContent(); try { bytes = IOUtils.toByteArray(objectData); } finally { IOUtils.closeQuietly(objectData); } } catch (SdkClientException e) { LOG.log(Level.WARNING, e.getMessage()); } return bytes; } @Override public String getBucketName() { return this.s3BucketName; } /** * Get S3 Filename. * @param folder {@link String} * @param asset {@link String} * @return {@link String} */ private String getFilename(final String folder, final String asset) { String filename = folder + "/" + asset + ".fkz"; return filename; } /** * @return {@link AmazonS3} */ private AmazonS3 getS3Connection() { if (this.s3client == null) { AWSCredentials credentials = new BasicAWSCredentials(this.s3AccessKey, this.s3AccessSecret); this.s3client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)).withRegion(Regions.US_WEST_2) // TODO create aws.properties .build(); } return this.s3client; } @Override public boolean isSupported() { return this.isSupported; } @Override public List<Bucket> listBuckets() { return getS3Connection().listBuckets(); } @Override public void reloadProperties() { String prop = this.systemDao.getValue(null, ASSET_SERVICE_S3); this.isSupported = Boolean.valueOf(prop).booleanValue(); if (this.isSupported) { this.s3AccessKey = this.systemDao.getValue(null, S3_ACCESS_KEY); this.s3AccessSecret = this.systemDao.getValue(null, S3_ACCESS_SECRET); this.s3BucketName = this.systemDao.getValue(null, S3_BUCKET_NAME); if (isEmpty(this.s3AccessKey) || isEmpty(this.s3AccessSecret) || isEmpty(this.s3BucketName)) { this.isSupported = false; LOG.log(Level.WARNING, "required system properties " + S3_ACCESS_KEY + ", " + S3_ACCESS_SECRET + ", " + S3_BUCKET_NAME); } } } @Override public void saveAsset(final String folder, final String asset, final byte[] bytes) { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(bytes.length); metadata.setContentType("application/zip"); try { String filename = getFilename(folder, asset); AmazonS3 connection = getS3Connection(); PutObjectRequest req = new PutObjectRequest(this.s3BucketName, filename, bis, metadata); connection.putObject(req); LOG.log(Level.FINE, "saving " + filename + " to " + S3_BUCKET_NAME); } finally { IOUtils.closeQuietly(bis); } } }