package org.openstack.atlas.logs.hadoop.sequencefiles; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.SequenceFile; import org.apache.hadoop.io.Writable; import org.apache.hadoop.io.SequenceFile; import org.apache.hadoop.util.ReflectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openstack.atlas.util.debug.Debug; import org.openstack.atlas.util.staticutils.StaticStringUtils; // Simulare to an Enumerator but allows Exceptions to be thrown public class SequenceFileIterator<K extends Writable, V extends Writable> { private static final Log LOG = LogFactory.getLog(SequenceFileIterator.class); protected SequenceFile.Reader reader; protected FileSystem fs; protected Configuration conf; protected Path path; protected Class keyClass; protected Class valueClass; protected int entryNumber = 0; public SequenceFileIterator(Path path, FileSystem fileSystem) throws SequenceFileReaderException { fs = fileSystem; conf = fs.getConf(); this.path = path; try { reader = new SequenceFile.Reader(fs, new Path(path.toUri().getPath()), conf); } catch (IOException ex) { String excMsg = Debug.getExtendedStackTrace(ex); String msg = String.format("IOException opening Sequence file %s for reading", path.toString()); LOG.error(String.format("%s: %s", msg, excMsg), ex); throw new SequenceFileReaderException(msg, ex); } keyClass = reader.getKeyClass(); valueClass = reader.getValueClass(); } public SequenceFileEntry<K, V> getNextEntry() throws SequenceFileReaderException, EndOfIteratorException { K key = (K) ReflectionUtils.newInstance(keyClass, conf); V value = (V) ReflectionUtils.newInstance(valueClass, conf); boolean hasNext; try { hasNext = reader.next(key, value); } catch (IOException ex) { String excMsg = Debug.getExtendedStackTrace(ex); String msg = String.format("IOException while attempting to read sequence file %s", path.toString()); LOG.error(String.format("%s: %s", msg, excMsg), ex); throw new SequenceFileReaderException(msg, ex); } if (!hasNext) { throw new EndOfIteratorException(); } SequenceFileEntry<K, V> out = new SequenceFileEntry(this.path.toUri().toString(), entryNumber, key, value); entryNumber++; return out; } public void close() { try { reader.close(); } catch (IOException ex) { LOG.warn(String.format("Coulden't close SequenceFileReader for %s assuming its already closed", path.toString())); } } }