package com.sumologic.kinesis;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.sumologic.client.KinesisConnectorForSumologicConfiguration;
import com.sumologic.client.SumologicMessageModelPipeline;
import com.sumologic.client.model.SimpleKinesisMessageModel;
import com.sumologic.kinesis.KinesisConnectorExecutorBase;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.services.kinesis.connectors.KinesisConnectorConfiguration;
import com.amazonaws.services.kinesis.connectors.interfaces.ITransformer;
/**
* This class defines the execution of a Amazon Kinesis Connector.
*
*/
public abstract class KinesisConnectorExecutor<T, U> extends KinesisConnectorExecutorBase<T, U> {
private static final Logger LOG = Logger.getLogger(KinesisConnectorExecutor.class.getName());
// Create Stream Source constants
private static final String CREATE_STREAM_SOURCE = "createStreamSource";
private static final String LOOP_OVER_STREAM_SOURCE = "loopOverStreamSource";
private static final String INPUT_STREAM_FILE = "inputStreamFile";
private static final boolean DEFAULT_CREATE_STREAM_SOURCE = false;
private static final boolean DEFAULT_LOOP_OVER_STREAM_SOURCE = false;
// Class variables
protected final KinesisConnectorForSumologicConfiguration config;
private final Properties properties;
/**
* Create a new KinesisConnectorExecutor based on the provided configuration (*.propertes) file.
*
* @param configFile
* The name of the configuration file to look for on the classpath
*/
public KinesisConnectorExecutor(String configFile) {
// Load configuration properties
InputStream configStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(configFile);
if (configStream == null) {
String msg = "Could not find resource " + configFile + " in the classpath";
throw new IllegalStateException(msg);
}
properties = new Properties();
try {
properties.load(configStream);
configStream.close();
} catch (IOException e) {
String msg = "Could not load properties file " + configFile + " from classpath";
throw new IllegalStateException(msg, e);
}
this.config = new KinesisConnectorForSumologicConfiguration(properties, getAWSCredentialsProvider());
LOG.info("Using " + configFile);
// Send sample data to AWS Kinesis if specified in the properties file
setupInputStream();
// Initialize executor with configurations
super.initialize((KinesisConnectorConfiguration)config);
}
/**
* Returns an {@link AWSCredentialsProvider} with the permissions necessary to accomplish all specified
* tasks. At the minimum it will require read permissions for Amazon Kinesis. Additional read permissions
* and write permissions may be required based on the Pipeline used.
*
* @return
*/
public AWSCredentialsProvider getAWSCredentialsProvider() {
return new ClasspathPropertiesFileCredentialsProvider("SumologicConnector.properties");
}
/**
* Helper method to spawn the {@link StreamSource} in a separate thread.
*/
private void setupInputStream() {
if (parseBoolean(CREATE_STREAM_SOURCE, DEFAULT_CREATE_STREAM_SOURCE, properties)) {
String inputFile = properties.getProperty(INPUT_STREAM_FILE);
StreamSource streamSource;
if (config.BATCH_RECORDS_IN_PUT_REQUEST) {
streamSource =
new BatchedStreamSource(config, inputFile, parseBoolean(LOOP_OVER_STREAM_SOURCE,
DEFAULT_LOOP_OVER_STREAM_SOURCE,
properties));
} else {
streamSource =
new StreamSource(config, inputFile, parseBoolean(LOOP_OVER_STREAM_SOURCE,
DEFAULT_LOOP_OVER_STREAM_SOURCE,
properties));
}
Thread streamSourceThread = new Thread(streamSource);
LOG.info("Starting stream source.");
streamSourceThread.start();
}
}
/**
* Helper method used to parse boolean properties.
*
* @param property
* The String key for the property
* @param defaultValue
* The default value for the boolean property
* @param properties
* The properties file to get property from
* @return property from property file, or if it is not specified, the default value
*/
private static boolean parseBoolean(String property, boolean defaultValue, Properties properties) {
return Boolean.parseBoolean(properties.getProperty(property, Boolean.toString(defaultValue)));
}
}