package com.cloudera.flume.source;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SshSpoolStateManager
{
private static final Logger logger =
LoggerFactory.getLogger(SshSpoolDirectorySource.class);
public enum FileProcessingState {
PENDING, IN_PROCESS, FAILED, SUCCEDED
}
protected HashMap< String, FileProcessingState > stateMap;
protected String filePath;
public SshSpoolStateManager( String filePath )
{
this.filePath = filePath + "/ssh-spool-state.out";
this.stateMap = new HashMap< String, FileProcessingState >();
loadMap();
// Mark any in-process files as errornoues
markUnprocessedAsError();
}
public ArrayList< String > getPending()
{
ArrayList< String > pending = new ArrayList< String >();
for( Map.Entry< String, FileProcessingState > entry: stateMap.entrySet() )
{
if( entry.getValue() == FileProcessingState.PENDING )
{
pending.add( entry.getKey() );
}
}
return pending;
}
public void addProcessingList( ArrayList< String > paths )
{
for( String file: paths )
{
if( !stateMap.containsKey( file ) )
{
stateMap.put( file, FileProcessingState.PENDING );
}
}
saveState();
}
public void markFinished( String file )
{
stateMap.put( file, FileProcessingState.SUCCEDED );
saveState();
}
public void markError( String file )
{
stateMap.put( file, FileProcessingState.FAILED );
saveState();
}
public void markInProcess( String file )
{
stateMap.put( file, FileProcessingState.IN_PROCESS );
saveState();
}
public void markUnprocessedAsError()
{
for( Map.Entry< String, FileProcessingState > entry: stateMap.entrySet() )
{
if( entry.getValue() == FileProcessingState.IN_PROCESS )
{
logger.info( entry.getKey() + " is marked as in_process, updating to error " );
entry.setValue( FileProcessingState.FAILED );
}
}
saveState();
}
public void saveState()
{
try {
saveMap();
} catch( IOException e ) {
logger.error( e.toString() );
logger.error( "SshSpoolStateManager: Unable to persist state to disk. Crashing..." );
System.exit(-1);
}
}
protected void saveMap() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream( filePath ));
oos.writeObject(stateMap);
oos.close();
}
protected void loadMap()
{
try{
ObjectInputStream ois = new ObjectInputStream( new FileInputStream( new File(filePath) ));
Object readMap = ois.readObject();
if(readMap != null && readMap instanceof HashMap) {
stateMap.putAll((HashMap) readMap);
}
ois.close();
} catch ( FileNotFoundException e ) {
} catch ( IOException e ) {
} catch ( ClassNotFoundException e ) {
// indicates the file doesnt exist.
// no worries, we'll start from scratch
}
}
}