package io.lumify.core.mapreduce; import io.lumify.core.bootstrap.InjectHelper; import io.lumify.core.bootstrap.LumifyBootstrap; import io.lumify.core.config.ConfigurationLoader; import io.lumify.core.util.LumifyLogger; import io.lumify.core.util.LumifyLoggerFactory; import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.mapred.JobConf; import org.apache.hadoop.mapreduce.Counter; import org.apache.hadoop.mapreduce.CounterGroup; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.util.Tool; import org.securegraph.accumulo.AccumuloGraphConfiguration; import org.securegraph.accumulo.mapreduce.AccumuloElementOutputFormat; import org.securegraph.accumulo.mapreduce.ElementMapper; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; public abstract class LumifyMRBase extends Configured implements Tool { private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(LumifyMRBase.class); public static final String CONFIG_SOURCE_FILE_NAME = "sourceFileName"; public static final int PERIODIC_COUNTER_OUTPUT_PERIOD = 30 * 1000; private String instanceName; private String zooKeepers; private String principal; private AuthenticationToken authorizationToken; private boolean local; private Timer periodicCounterOutputTimer; @Override public int run(String[] args) throws Exception { io.lumify.core.config.Configuration lumifyConfig = ConfigurationLoader.load(); JobConf conf = getConfiguration(args, lumifyConfig); AccumuloGraphConfiguration accumuloGraphConfiguration = new AccumuloGraphConfiguration(conf, "graph."); InjectHelper.inject(this, LumifyBootstrap.bootstrapModuleMaker(lumifyConfig), lumifyConfig); Job job = Job.getInstance(conf, getJobName()); instanceName = accumuloGraphConfiguration.getAccumuloInstanceName(); zooKeepers = accumuloGraphConfiguration.getZookeeperServers(); principal = accumuloGraphConfiguration.getAccumuloUsername(); authorizationToken = accumuloGraphConfiguration.getAuthenticationToken(); AccumuloElementOutputFormat.setOutputInfo(job, instanceName, zooKeepers, principal, authorizationToken); boolean periodicCounterOutput = conf.getBoolean("lumify.periodic.counter.output.enabled", false); if (job.getConfiguration().get("mapred.job.tracker").equals("local")) { LOGGER.warn("!!!!!! Running in local mode !!!!!!"); local = true; periodicCounterOutput = true; } setupJob(job); if (periodicCounterOutput) { startPeriodicCounterOutputThread(job); } LOGGER.info("Starting job"); long startTime = System.currentTimeMillis(); int result = job.waitForCompletion(true) ? 0 : 1; long endTime = System.currentTimeMillis(); LOGGER.info("Job complete"); if (periodicCounterOutputTimer != null) { periodicCounterOutputTimer.cancel(); } printCounters(job); LOGGER.info("Time: %,.2f minutes", ((double) (endTime - startTime) / 1000.0 / 60.0)); LOGGER.info("Return code: " + result); return result; } public boolean isLocal() { return local; } protected void printCounters(Job job) { try { LOGGER.info("Counters"); for (String groupName : job.getCounters().getGroupNames()) { CounterGroup groupCounters = job.getCounters().getGroup(groupName); LOGGER.info(groupCounters.getDisplayName()); for (Counter counter : groupCounters) { LOGGER.info(" " + counter.getDisplayName() + ": " + counter.getValue()); } } } catch (IOException ex) { LOGGER.error("Could not print counters", ex); } } protected abstract String getJobName(); protected abstract void setupJob(Job job) throws Exception; protected JobConf getConfiguration(String[] args, io.lumify.core.config.Configuration lumifyConfig) { Configuration hadoopConfig = lumifyConfig.toHadoopConfiguration(getConf()); hadoopConfig.set(ElementMapper.GRAPH_CONFIG_PREFIX, "graph."); JobConf result = new JobConf(hadoopConfig, this.getClass()); parseArgs(result, args); setConf(result); LOGGER.info("Using config:\n" + result); return result; } protected abstract void parseArgs(JobConf conf, String[] args); public String getInstanceName() { return instanceName; } public String getZooKeepers() { return zooKeepers; } public String getPrincipal() { return principal; } public AuthenticationToken getAuthorizationToken() { return authorizationToken; } private void startPeriodicCounterOutputThread(final Job job) { periodicCounterOutputTimer = new Timer("periodicCounterOutput", true); TimerTask task = new TimerTask() { @Override public void run() { printCounters(job); } }; periodicCounterOutputTimer.scheduleAtFixedRate(task, PERIODIC_COUNTER_OUTPUT_PERIOD, PERIODIC_COUNTER_OUTPUT_PERIOD); } }