package org.kisst.gft.poller; import org.kisst.gft.GftContainer; import org.kisst.gft.filetransfer.FileServer; import org.kisst.gft.filetransfer.FileServerConnection; import org.kisst.gft.filetransfer.LocalFileServer; import org.kisst.props4j.Props; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Poller implements Runnable { private static final Logger logger = LoggerFactory.getLogger(Poller.class); public final GftContainer gft; private final Props props; private final int interval; private final String name; private final PollerJob[] jobs; private boolean running=true; private boolean paused=false; private Thread thread=null; private boolean sleeping=false; //public final SshHost server; private final FileServer fileserver; public Poller(GftContainer gft, String name, Props props) { this.gft = gft; this.props = props; this.name = name; this.interval = props.getInt("interval", 1000); if (gft != null) { String hostname = props.getString("host", null); if (hostname != null) { logger.info("using remote host {}", hostname); fileserver = gft.getFileServer(hostname); } else { logger.info("using local host"); fileserver = new LocalFileServer(props); } } else fileserver = new LocalFileServer(props); paused=props.getBoolean("paused", false); Props pollerProps = props.getProps("job", null); if (pollerProps == null) jobs = new PollerJob[0]; else { int count = 0; for (@SuppressWarnings("unused") String jobname : pollerProps.keys()) count++; jobs = new PollerJob[count]; int i = 0; for (String jobname : pollerProps.keys()) jobs[i++] = new PollerJob(this, pollerProps.getProps(jobname)); } } public Poller(String name, Props props) { this(null, name, props); } public String getName() { return name; } public boolean isPaused() { return paused; } public boolean isRunning() { return thread!=null; } public int getInterval() { return interval; } public Props getProps() { return props; } public FileServer getFileServer() { return this.fileserver; } public void reset() { for (PollerJob job: jobs) job.reset(); } public boolean hasTag(String tag) { for (PollerJob job: jobs) { if (job.hasTag(tag)) return true; } return false; } public PollerJob[] getJobs() { return jobs; } public synchronized void start() { if (thread!=null) throw new RuntimeException("Poller "+name+"already started"); thread=new Thread(this); thread.start(); } public synchronized void stop() { if (thread==null) throw new RuntimeException("Poller "+name+" not running"); logger.info("Stopping poller {}",name); running=false; if (sleeping) // TODO: not really thread safe thread.interrupt(); thread=null; } public void pause() { logger.info("Pause poller {}",name); paused=true; } // TODO: This method could use some more precise exception handling public void run() { logger.info("Starting poller {}",name); while (running) { try { FileServerConnection fsconn=null; if (! paused){ if (fileserver!=null) fsconn=fileserver.openConnection(); for (PollerJob job: jobs) { try { job.runOnce(fsconn); } catch (Exception e) { logger.error("error when running PollerJob "+job.getName()+" in poller "+getName(),e ); } } } if (fsconn!=null) fsconn.close(); } catch (Exception e) { logger.error("error in poller "+getName(), e); } sleeping=true; try { Thread.sleep(interval); } catch (InterruptedException e) { /*IGNORE*/ } sleeping=false; } logger.info("Stopped poller {}",name); } public void resume() { logger.info("Resume poller {}",name); paused=false; } public void join() throws InterruptedException { if (thread==null) return; thread.join(); } }