package org.cfg4j.source.s3; import com.amazonaws.services.kms.model.NotFoundException; import com.amazonaws.services.s3.model.S3Object; import org.cfg4j.source.ConfigurationSource; import org.cfg4j.source.context.environment.Environment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; import java.util.Properties; /** * Note: use {@link S3ConfigurationSourceBuilder} for building instances of this class. * <p> * Read configuration files from AWS S3. * </p> */ public class S3ConfigurationSource implements ConfigurationSource { private static final Logger LOG = LoggerFactory.getLogger(S3ConfigurationSource.class); private boolean initialized = false; private AmazonS3Wrapper s3wrapper; /** * Note: use {@link S3ConfigurationSourceBuilder} for building instances of this class. * <p> * Read configuration for an AWS S3 bucket and credentials defined in the {@code AmazonS3Wrapper} * </p> * @param s3wrapper Pre-configured wrapper for the S3 service */ public S3ConfigurationSource(AmazonS3Wrapper s3wrapper){ this.s3wrapper = s3wrapper; } /** * Note: use {@link S3ConfigurationSourceBuilder} for building instances of this class. * @param accessKey An API access key for your AWS account * @param secretKey An API secret key for your AWS account * @param bucketName The name of the bucket where configuration files are located */ public S3ConfigurationSource(String accessKey, String secretKey, String bucketName) { this.s3wrapper = new AmazonS3WrapperImpl(accessKey, secretKey, bucketName); } /** * Get the configuration properties for the corresponding environment from S3 * @param environment environment to use * @return A {@link Properties} collection extracted from the configuration file * * @throws IllegalStateException when {@code init()} is not called prior to calling {@code getConfiguration} * @throws IllegalArgumentException when an empty string is passed in for the {@link Environment} name * or when the file cannot be parsed properly * @throws NotFoundException when a file corresponding to the requested environment is not found */ @Override public Properties getConfiguration(Environment environment) { LOG.trace("Requesting configuration for environment: " + environment.getName()); if (!initialized) { throw new IllegalStateException("Configuration source has to be successfully initialized before you request configuration."); } if(environment.getName().isEmpty()){ throw new IllegalArgumentException("Environment must not be null or empty"); } if (!s3wrapper.isFileExist(environment.getName())) { throw new NotFoundException(MessageFormat.format("File name {0} does not exist", environment.getName())); } S3Object fileFromS3 = s3wrapper.getFile(environment.getName()); Properties properties = new Properties(); try (InputStream input = fileFromS3.getObjectContent()) { properties.load(input); } catch (IOException e) { throw new IllegalArgumentException("Unable to load configuration from " + environment.getName() + " file", e); } finally { try { fileFromS3.close(); } catch (IOException e) { e.printStackTrace(); } } return properties; } /** * @throws ExceptionInInitializerError when the requested bucket does not exist */ @Override public void init() { LOG.info("Connecting to s3..."); s3wrapper.init(); if (!s3wrapper.isBucketExist(getBucketName())) { throw new ExceptionInInitializerError(MessageFormat.format("Given bucket ''{0}'' does not exist", getBucketName())); } initialized = true; } public String getBucketName() { return s3wrapper.getBucketName(); } public void setBucketName(String bucketName) { s3wrapper.setBucketName(bucketName); } }