fork download
  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.io.Serializable;
  4. import java.io.StringWriter;
  5. import java.text.DateFormat;
  6. import java.text.SimpleDateFormat;
  7. import java.util.ArrayList;
  8. import java.util.Calendar;
  9. import java.util.GregorianCalendar;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.Timer;
  13. import java.util.TimerTask;
  14.  
  15. import javax.sql.DataSource;
  16.  
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.jdbc.core.JdbcTemplate;
  20. import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
  21. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
  22. import org.springframework.jdbc.support.GeneratedKeyHolder;
  23. import org.springframework.jdbc.support.KeyHolder;
  24.  
  25. /**
  26.  * Object responsible for creating EmailJobs and EmailJobWorkers. Also responsible for starting EmailJobWorkers once their start time has been reached.
  27.  * Also responsible for removing files and tables associated with email jobs upon a request from a user to remove them.
  28.  *
  29.  *
  30.  * @version 1.0.0
  31.  */
  32. public class EmailJobManager implements Serializable
  33. {
  34. private static final long serialVersionUID = 1L;
  35.  
  36. private static Logger logger = LoggerFactory.getLogger(EmailJobManager.class.getName());
  37.  
  38. /**Location on server of HTML files used for emails*/
  39. public static final String HTML_FILE_DIR = "C:\\test\\";
  40.  
  41. /**Delay in minutes before the manager checks to see if any jobs need to start*/
  42. private final int JOB_CHECK_DELAY = 1;
  43.  
  44. /*Spring JDBC objects*/
  45. private DataSource ds;
  46. private transient JdbcTemplate jt;
  47. private transient NamedParameterJdbcTemplate njt;
  48.  
  49. /**List of all workers still currently actively sending out emails*/
  50. private List<EmailJobWorker> activeWorkers = new ArrayList<EmailJobWorker>();
  51. /**List of workers that completed their jobs*/
  52. private List<EmailJobWorker> finishedWorkers = new ArrayList<EmailJobWorker>();
  53. /**List of paused workers*/
  54. private List<EmailJobWorker> pausedWorkers = new ArrayList<EmailJobWorker>();
  55.  
  56. /**Timer that fires telling manager to check to see if jobs need to be started, or moved to finished list*/
  57. private transient Timer jobCheckTimer = new Timer("EmailJobManager");
  58.  
  59. public EmailJobManager(DataSource ds)
  60. {
  61. this.njt = new NamedParameterJdbcTemplate(ds);
  62. this.ds = ds;
  63. this.jt = new JdbcTemplate(ds);
  64.  
  65. loadJobs();
  66.  
  67. jobCheckTimer.schedule(new TimerTask(){
  68.  
  69. @Override
  70. public void run()
  71. {
  72. logger.info("EmailJobManager timer run started.");
  73.  
  74.  
  75. for(EmailJobWorker worker: activeWorkers)
  76. {
  77. logger.info("EmailJobWorker " + worker.getEmailJobName() + " is an active worker.");
  78. logger.info("Memory Address in manager timer loop 1 for " + worker.getEmailJobName() + " ({})", worker.toString());
  79. }
  80.  
  81.  
  82. logger.info("Size of pausedWorkers: {}", pausedWorkers.size());
  83.  
  84. for(EmailJobWorker worker : pausedWorkers)
  85. {
  86. logger.info("Memory Address in manager timer loop 2 for " + worker.getEmailJobName() + " ({})", worker.toString());
  87.  
  88. SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy - HH:mm");
  89.  
  90. logger.info("Comparing current time ({}) to EmailJobWorker " + worker.getEmailJobName() + " start time ({})", sdf.format(c.getTime()), sdf.format(worker.getStartDate()));
  91.  
  92. if(c.compareTo(worker.getEmailJob().getStartTime()) > 0)
  93. {
  94. pausedWorkers.remove(worker);
  95. activeWorkers.add(worker);
  96. worker.start();
  97. logger.info("EmailJob " + worker.getEmailJob().getJobName() + " started.\n");
  98. }
  99. }
  100.  
  101. for(EmailJobWorker worker : activeWorkers)
  102. {
  103. if(worker.isCompleted())
  104. {
  105. activeWorkers.remove(worker);
  106. finishedWorkers.add(worker);
  107. logger.info("Worker " + worker.getEmailJobName() + " has completed.");
  108. }
  109. }
  110. }
  111.  
  112. }, 0, /*interval in milliseconds*/JOB_CHECK_DELAY * 60 * 1000);
  113.  
  114. logger.info("EmailJobManager timer started sucesfully. (sleepTime) ({})", JOB_CHECK_DELAY);
  115. }
  116.  
  117. /**
  118. * Adds new email job to this manager's duties.
  119. *
  120. * @param jobName Name of the email job
  121. * @param startTime Time for the email job to start
  122. * @param batchSize Number of emails to be sent out per time interval
  123. * @param timeInterval Time between batches in minutes
  124. * @param emailSubject Subject of the email
  125. * @param fromAddress The email address the emails will be sent from
  126. * @param password Password of the email address
  127. * @throws IOException If HTML file to be used for the email is not found
  128. */
  129. public void addJob(String jobName, Calendar startTime, int batchSize, int timeInterval, String emailSubject, String fromAddress, String password) throws IOException
  130. {
  131. String SQL = "INSERT INTO email_jobs (jobName, emailSubject, email, password, startTime, batchSize, timeInterval) VALUES(:jobName, :emailSubject, :email, :password, :startTime, :batchSize, :timeInterval)";
  132. MapSqlParameterSource params = new MapSqlParameterSource();
  133. params.addValue("jobName", jobName);
  134. params.addValue("emailSubject", emailSubject);
  135. params.addValue("email", fromAddress);
  136. params.addValue("password", password);
  137. DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
  138. params.addValue("startTime", dateFormat.format(startTime.getTime()));
  139. params.addValue("batchSize", batchSize);
  140. params.addValue("timeInterval", timeInterval);
  141. KeyHolder keyHolder = new GeneratedKeyHolder();
  142. njt.update(SQL, params, keyHolder);
  143. int jobId = keyHolder.getKey().intValue();
  144.  
  145. EmailJob job = new EmailJob(jobId, jobName, startTime, HTML_FILE_DIR + "/" + jobName + ".html");
  146.  
  147. EmailJobWorker newWorker = new EmailJobWorker(job, batchSize, timeInterval, ds, emailSubject, fromAddress, password);
  148.  
  149. logger.info("Memory Address in addJob for " + newWorker.getEmailJobName() + " ({})", newWorker.toString());
  150.  
  151. activeWorkers.add(newWorker);
  152. }
  153.  
  154. /**
  155. * Pauses a job that is currently running.
  156. *
  157. * @param jobName Name of the job to pause.
  158. */
  159. public void pauseJob(String jobName)
  160. {
  161. for(EmailJobWorker worker : activeWorkers)
  162. {
  163. if(worker.getEmailJob().getJobName().equals(jobName))
  164. {
  165. activeWorkers.remove(worker);
  166. pausedWorkers.add(worker);
  167. worker.stop();
  168. return;
  169. }
  170. }
  171. }
  172.  
  173. public void startJob(String jobName)
  174. {
  175. for(EmailJobWorker worker : pausedWorkers)
  176. {
  177. if(worker.getEmailJobName().equals(jobName))
  178. {
  179. pausedWorkers.remove(worker);
  180. activeWorkers.add(worker);
  181. worker.start();
  182. return;
  183. }
  184. }
  185.  
  186. for(EmailJobWorker worker : finishedWorkers)
  187. {
  188. if(worker.getEmailJobName().equals(jobName))
  189. {
  190. finishedWorkers.remove(worker);
  191. activeWorkers.add(worker);
  192. worker.restart();
  193. return;
  194. }
  195. }
  196. }
  197.  
  198. public void destroyJob(String jobName)
  199. {
  200. for(EmailJobWorker worker : getActiveWorkers())
  201. {
  202. if(worker.getEmailJobName().equals(jobName))
  203. {
  204. worker.stop();
  205. activeWorkers.remove(worker);
  206. }
  207. }
  208.  
  209. for(EmailJobWorker worker : getPausedWorkers())
  210. {
  211. if(worker.getEmailJobName().equals(jobName))
  212. {
  213. worker.stop();
  214. pausedWorkers.remove(worker);
  215. }
  216. }
  217.  
  218. for(EmailJobWorker worker : getFinishedWorkers())
  219. {
  220. if(worker.getEmailJobName().equals(jobName))
  221. {
  222. finishedWorkers.remove(worker);
  223. }
  224. }
  225. }
  226.  
  227. public List<EmailJobWorker> getActiveWorkers()
  228. {
  229. return this.activeWorkers;
  230. }
  231.  
  232. public List<EmailJobWorker> getPausedWorkers()
  233. {
  234. return this.pausedWorkers;
  235. }
  236.  
  237. public List<EmailJobWorker> getFinishedWorkers()
  238. {
  239. return this.finishedWorkers;
  240. }
  241.  
  242. /**
  243. * Checks to see if any jobs were not completed as expected due to hardware error. Recreates the EmailJob and EmailJobWorker responsible.
  244. */
  245. private void loadJobs()
  246. {
  247. String SQL = "SELECT * FROM email_jobs";
  248.  
  249. List<Map<String, Object>> rows = jt.queryForList(SQL);
  250.  
  251. for(Map<String, Object> row : rows)
  252. {
  253. int jobId = (Integer)row.get("id");
  254. String jobName = (String)row.get("jobName");
  255. String emailSubject = (String)row.get("emailSubject");
  256. String email = (String)row.get("email");
  257. String password = (String)row.get("password");
  258. Calendar startTime = new GregorianCalendar();
  259. startTime.setTime((java.util.Date)row.get("startTime"));
  260. int batchSize = (Integer)row.get("batchSize");
  261. int timeInterval = (Integer)row.get("timeInterval");
  262. boolean completed = (Boolean)row.get("completed");
  263. boolean paused = (Boolean)row.get("paused");
  264.  
  265. //Get id of next email to be sent out
  266. SQL = "SELECT MIN(id) FROM " + jobName + "_email_list" + " WHERE sentOut = false";
  267. int startId = njt.queryForInt(SQL, new MapSqlParameterSource());
  268.  
  269. EmailJob job;
  270. try
  271. {
  272. job = new EmailJob(jobId, jobName, startTime, HTML_FILE_DIR + "/" + jobName + ".html");
  273. }
  274. catch (IOException e)
  275. {
  276. e.printStackTrace(new PrintWriter(sw));
  277. String stackTrace = sw.toString();
  278.  
  279. logger.error("EmailJob " + jobName + " failed to load. HTML file at " + HTML_FILE_DIR + "/" + jobName + ".html" + " was not found.\n" + stackTrace + "\n");
  280.  
  281. continue;
  282. }
  283.  
  284. EmailJobWorker worker = new EmailJobWorker(job, batchSize, timeInterval, ds, emailSubject, email, password, startId);
  285.  
  286. if(completed)
  287. {
  288. finishedWorkers.add(worker);
  289. logger.info("EmailJobWorker " + jobName + " has been added to the finished worker pool.");
  290. }
  291. else
  292. {
  293. logger.info("Worker " + worker.getEmailJobName() + " has been added to pausedWorkers list with memory address ({})", worker.toString());
  294. pausedWorkers.add(worker);
  295. }
  296.  
  297. logger.info("EmailJob " + jobName + " loaded sucessfully.");
  298. }
  299. }
  300. }
  301.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty