More Java Fun

I’m implementing sort of a half-assed Control-M system in J2EE.  Here’s some preview code:


Job.java:

/**
 * 
 */
package entity;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Calendar;

import org.jboss.logging.Logger;

/**
 * @author imbrius
 * 
 *         A Job is the basic unit of work. It contains live executable code and
 *         is runnable by adding it to a queue.
 */
public class Job implements Runnable, Serializable {
	/**
	 *
	 */
	private static final long serialVersionUID = 8641665211731936755L;
	// private long uid;
	// private long gid;
	// private long euid;
	// private long egid;
	private File cwd;
	// private long pid;
	// private long c_ptab_ent;
	private int jobId;
	private int retval;
	private long submitTime;
	private long completeTime;
	// private long t_real;
	// private long t_user;
	// private long t_sys;
	private long timeElapsed;
	private String stdout;
	private String stderr;
	private String text;
	private File f_stdin;
	private String s_stdin;
	private String[] envp;
	/**
	 * Holds the job status
	 * 
	 * 00 - Stopped
	 * 01 - /unused/
	 * 02 - Running
	 * 03 - /unused/
	 * 33 - No Job Found (useful only as a query result - setting a job's
	 *      status to this breaks things.
	 * 99 - Stopped with no last run
	 */
	private int status;
	private String name;

	private static final Logger log = Logger.getLogger(Job.class.getName());

	public Job(int id) {
		jobId = id;
		cwd = new File("./");
		status = 99;
	}

	public Job(int id, String name, File cwd, String text, File f_stdin, String s_stdin,
			String[] envp) {
		this.jobId = id;
		this.name = name;
		this.cwd = cwd;
		this.text = text;
		this.f_stdin = f_stdin;
		this.s_stdin = s_stdin;
		this.envp = envp;
		status = 99;
	}

	public Job(int id, String name, String s_cwd, String text, File f_stdin, String s_stdin,
			String[] envp) {
		this.jobId = id;
		this.name = name;
		this.cwd = new File(s_cwd);
		this.text = text;
		this.f_stdin = f_stdin;
		this.s_stdin = s_stdin;
		this.envp = envp;
		status = 99;
	}

	@Override
	public void run() {

		// FIXME Current implementation is thread-blind. The runtime will
		// create a new Java thread to execute the job text but any kernel
		// or OS threads created by running the job text will be invisible to
		// Java. We're relying on the OS to do the Right Thing when reporting
		// run info after the job completes.

		status = 02;
		Runtime runtime = Runtime.getRuntime();
		Process pr = null;
		OutputStream os;

		try {
			submitTime = Calendar.getInstance().getTimeInMillis();
			pr = runtime.exec(text, getEnvp(), cwd);
			os = pr.getOutputStream();

			if (f_stdin.length() > 0) {
				BufferedReader inputFileReader = new BufferedReader(
						new FileReader(f_stdin));
				while (inputFileReader.ready()) {
					os.write(inputFileReader.read());
				}
			}

			else if (s_stdin.length() > 0) {
				os.write(s_stdin.getBytes());
			}
		}

		catch (IOException ioex) {
			log.error(ioex.getMessage(), ioex);
		}

		try {
			pr.waitFor();
			completeTime = Calendar.getInstance().getTimeInMillis();
			timeElapsed = completeTime - submitTime;
		}

		catch (InterruptedException iex) {
			log.error(iex.getMessage(), iex);
		}

		BufferedReader b_stdout = new BufferedReader(new InputStreamReader(
				pr.getInputStream()));
		BufferedReader b_stderr = new BufferedReader(new InputStreamReader(
				pr.getErrorStream()));

		try {
			stdout = new String();
			String line = new String();
			while ((line = b_stdout.readLine()) != null) {
				stdout.concat(line);
			}

			stderr = new String();
			line = new String();
			while ((line = b_stderr.readLine()) != null) {
				stderr.concat(line);
			}
		}

		catch (IOException ioex) {
			log.error(ioex.getMessage(), ioex);
		}

		retval = pr.exitValue();
		status = 00;
	}

	// /**
	// * @param uid the uid to set
	// */
	// public void setUid(long uid) {
	// this.uid = uid;
	// }
	//
	// /**
	// * @return the uid
	// */
	// public long getUid() {
	// return uid;
	// }
	//
	// /**
	// * @param gid the gid to set
	// */
	// public void setGid(long gid) {
	// this.gid = gid;
	// }
	//
	// /**
	// * @return the gid
	// */
	// public long getGid() {
	// return gid;
	// }
	//
	// /**
	// * @param euid the euid to set
	// */
	// public void setEuid(long euid) {
	// this.euid = euid;
	// }
	//
	// /**
	// * @return the euid
	// */
	// public long getEuid() {
	// return euid;
	// }
	//
	// /**
	// * @param egid the egid to set
	// */
	// public void setEgid(long egid) {
	// this.egid = egid;
	// }
	//
	// /**
	// * @return the egid
	// */
	// public long getEgid() {
	// return egid;
	// }

	/**
	 * @param cwd
	 *            the cwd to set
	 */
	public void setCwd(File cwd) {
		this.cwd = cwd;
	}

	/**
	 * @return the cwd
	 */
	public File getCwd() {
		return cwd;
	}

	// /**
	// * @param pid the pid to set
	// */
	// public void setPid(long pid) {
	// this.pid = pid;
	// }
	//
	// /**
	// * @return the pid
	// */
	// public long getPid() {
	// return pid;
	// }
	//
	// /**
	// * @param c_ptab_ent the c_ptab_ent to set
	// */
	// public void setC_ptab_ent(long c_ptab_ent) {
	// this.c_ptab_ent = c_ptab_ent;
	// }
	//
	// /**
	// * @return the c_ptab_ent
	// */
	// public long getC_ptab_ent() {
	// return c_ptab_ent;
	// }
	//
	/**
	 * @param jobId
	 *            the jobId to set
	 */
	public void setJobId(int jobId) {
		this.jobId = jobId;
	}

	/**
	 * @return the jobId
	 */
	public int getJobId() {
		return jobId;
	}

	/**
	 * @param submitTime
	 *            the submitTime to set
	 */
	public void setSubmitTime(long submitTime) {
		this.submitTime = submitTime;
	}

	/**
	 * @return the submitTime
	 */
	public long getSubmitTime() {
		return submitTime;
	}

	/**
	 * @param completeTime
	 *            the completeTime to set
	 */
	public void setCompleteTime(long completeTime) {
		this.completeTime = completeTime;
	}

	/**
	 * @return the completeTime
	 */
	public long getCompleteTime() {
		return completeTime;
	}

	// /**
	// * @param t_real the t_real to set
	// */
	// public void setT_real(long t_real) {
	// this.t_real = t_real;
	// }
	//
	// /**
	// * @return the t_real
	// */
	// public long getT_real() {
	// return t_real;
	// }
	//
	// /**
	// * @param t_user the t_user to set
	// */
	// public void setT_user(long t_user) {
	// this.t_user = t_user;
	// }
	//
	// /**
	// * @return the t_user
	// */
	// public long getT_user() {
	// return t_user;
	// }
	//
	// /**
	// * @param t_sys the t_sys to set
	// */
	// public void setT_sys(long t_sys) {
	// this.t_sys = t_sys;
	// }
	//
	// /**
	// * @return the t_sys
	// */
	// public long getT_sys() {
	// return t_sys;
	// }

	// /**
	// * @param stdout the stdout to set
	// */
	// public void setStdout(String stdout) {
	// this.stdout = stdout;
	// }

	/**
	 * @return the stdout
	 */
	public String getStdout() {
		return stdout;
	}

	// /**
	// * @param stderr the stderr to set
	// */
	// public void setStderr(String stderr) {
	// this.stderr = stderr;
	// }

	/**
	 * @return the stderr
	 */
	public String getStderr() {
		return stderr;
	}

	/**
	 * @param text
	 *            the text to set
	 */
	public void setText(String text) {
		this.text = text;
	}

	/**
	 * @return the text
	 */
	public String getText() {
		return text;
	}

	/**
	 * @param f_stdin
	 *            the f_stdin to set
	 */
	public void setF_stdin(File f_stdin) {
		this.f_stdin = f_stdin;
	}

	/**
	 * @return the f_stdin
	 */
	public File getF_stdin() {
		return f_stdin;
	}

	/**
	 * @param s_stdin
	 *            the s_stdin to set
	 */
	public void setS_stdin(String s_stdin) {
		this.s_stdin = s_stdin;
	}

	/**
	 * @return the s_stdin
	 */
	public String getS_stdin() {
		return s_stdin;
	}

	/**
	 * @param envp
	 *            the envp to set
	 */
	public void setEnvp(String[] envp) {
		this.envp = envp;
	}

	/**
	 * @return the envp
	 */
	public String[] getEnvp() {
		return envp;
	}

	// /**
	// * @param retval the retval to set
	// */
	// public void setRetval(int retval) {
	// this.retval = retval;
	// }

	/**
	 * @return the retval
	 */
	public int getRetval() {
		return retval;
	}

	// /**
	// * @param timeElapsed the timeElapsed to set
	// */
	// public void setTimeElapsed(long timeElapsed) {
	// this.timeElapsed = timeElapsed;
	// }

	/**
	 * @return the timeElapsed
	 */
	public long getTimeElapsed() {
		return timeElapsed;
	}

	/**
	 * @param status
	 *            the status to set
	 */
	public void setStatus(int status) {
		this.status = status;
	}

	/**
	 * @return the status
	 * 00 - Stopped
	 * 01 - /unused/
	 * 02 - Running
	 * 03 - /unused/
	 * 33 - No Job Found (useful only as a query result - setting a job's
	 *      status to this breaks things.
	 * 99 - Stopped with no last run
	 */
	public int getStatus() {
		return status;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

}

JobService.java:

package service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import entity.Job;

/**
 * Session Bean implementation class JobService
 */
@Stateless(mappedName = "JobService")
@TransactionManagement(TransactionManagementType.BEAN)
public class JobService implements JobServiceRemote {

	private List<Job> jobs;
	private int idPool;

	/**
	 * Default constructor.
	 */
	public JobService() {
		jobs = new ArrayList<Job>();
	}

	@Override
	public List<Job> listJobs() {
		return jobs;
	}

	@Override
	public Job createJob(String name, File cwd, String text, File f_stdin,
			String s_stdin, String[] envp) {
		Job job = new Job(getNextId(), name, cwd, text, f_stdin, s_stdin, envp);
		jobs.add(job);
		return job;
	}

	@Override
	public Job createJob(String name, String s_cwd, String text, File f_stdin,
			String s_stdin, String[] envp) {
		return createJob(name, new File(s_cwd), text, f_stdin, s_stdin, envp);
	}

	@Override
	public Job getJob(int jobId) {
		for (Job j : jobs) {
			if (j.getJobId() == jobId) {
				return j;
			}
		}

		return null;
	}

	@Override
	public int queryJob(int jobId) {
		Job j = getJob(jobId);
		return j != null ? j.getStatus() : 33; // ENOJOB
	}

	// @Override
	// public void queueJob(int jobId) {
	// // TODO Auto-generated method stub
	//
	// }
	//
	// @Override
	// public void queueJob(int jobId, int batchId) {
	// // TODO Auto-generated method stub
	//
	// }
	//
	// @Override
	// public void queueJob(int jobId, long startTime) {
	// // TODO Auto-generated method stub
	//
	// }

	@Override
	public void deleteJob(int jobId) {
		Job j = getJob(jobId);

		if (j != null) {
			jobs.remove(j);
		}
	}

	@Override
	public Job getJob(String name) {
		for (Job j : jobs) {
			if (j.getName() == name) {
				return j;
			}
		}

		return null;
	}

	@Override
	public int queryJob(String name) {
		Job j = getJob(name);
		return j != null ? j.getStatus() : 33; // ENOJOB
	}

	@Override
	public void deleteJob(String name) {
		Job j = getJob(name);
		
		if (j != null) {
			jobs.remove(j);
		}

	}

	private int getNextId() {
		if (idPool == 2147483646 /* 32 bit signed int */) {
			idPool = 0;
		}

		boolean found = false;
		while (idPool < 2147483646 /* 32 bit signed int */) {
			for (Job j : jobs) {
				if (j.getJobId() == idPool) {
					found = true;
					break;
				}
			}

			if (!found) {
				return idPool;
			}

			idPool++;
			found = false;
		}

		return -1;
	}

}

Advertisements

, , , , , , , , , , ,

  1. #1 by Joshua on July 10, 2011 - 3:17 PM

    Recursion drives me bananas… keeping one calling level separate from another in my head is difficult. Thankfully, Eclipse’s debugger is great at handling recursion. 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: