/** * Copyright [2011] [Datasalt Systems S.L.] * * 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.datasalt.utils.commons; import java.io.IOException; import java.util.Properties; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.Job; /** * A BaseJob ready for deal with Hadoop Jobs. Override the getJob() * method to supply your own Hadoop Job. * <br/> * Override getJobGeneratedProperties() to return back properties to * Azkaban * <br/> * * @author ivan */ public abstract class BaseHadoopJob extends BaseJob { boolean submitted = false; Job theJob; /** * This method receives the Job's parameters just as they are passed from the command line. The Hadoop Configuration is provided externally depending on the use case. * * @param args The command-line-style arguments needed to instantiate this Job * @param conf The provided Configuration * @return The Hadoop Job configured according to the arguments and the provided Configuration * * @throws IOException */ public abstract Job getJob(String[] args, Configuration conf) throws IOException; /** * This method can be used to return properties from this job (e.g. counters, statistics, generated properties...) * to Azkaban * * */ public abstract Properties getJobGeneratedProperties(Job job); @Override public Properties getJobGeneratedProperties() { return getJobGeneratedProperties(theJob); } /** * Get the progress: [0, 0.5] for map phase, [0.5, 1.0] for reduce phase. Right now this is not working as Azkaban doesn't implement progress polling from Java processes. * * @return The progress of the Job based on Map / Reduce phases progress * @throws Exception */ @Override public double getProgress() throws Exception { /* * We can't query for the Job progress meanwhile it is being defined */ if(!submitted) { return 0.0; } if(theJob.reduceProgress() == 0.0) { return theJob.mapProgress() * 0.5; } return theJob.reduceProgress() * 0.5 + 0.5; } /** * Cancel this Job: it will also cancel the Hadoop Job by killing it in the Job Tracker. * */ @Override public void cancel() throws Exception { theJob.killJob(); } @Override public void execute(String[] args, Configuration conf) throws IOException, InterruptedException, ClassNotFoundException { theJob = getJob(args, conf); theJob.submit(); submitted = true; boolean success = theJob.waitForCompletion(true); if (!success) { throw new IOException("JOB FAILED!"); } } }