// Path: src/main/java/yourwebproject2/model/entity/Job.java
// @Entity
// @Table(indexes = {  @Index(name="name_idx", columnList = "name", unique = true),
//         @Index(name="status_idx", columnList = "status"),
//         @Index(name="category_idx", columnList = "category")})
// public class Job extends JPAEntity<Long> {
//     public enum Status {
//         NEW, EXECUTING, PRIORITIZED, FAILED, RETRYING, SUCCESSFUL
//     }
// 
//     private String name;
//     private String metadataJson;
//     private String callbackUrl;
//     private Date submitTime;
//     private Status status;
//     private Date scheduledTime;
//     private Date completionTime;
//     private Integer retryCount;
//     private Category category;
// 
//     @NotNull @NotBlank
//     @Column
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     @Column
//     public String getCallbackUrl() {
//         return callbackUrl;
//     }
// 
//     public void setCallbackUrl(String callbackUrl) {
//         this.callbackUrl = callbackUrl;
//     }
// 
//     @Column
//     public String getMetadataJson() {
//         return metadataJson;
//     }
// 
//     public void setMetadataJson(String metadataJson) {
//         this.metadataJson = metadataJson;
//     }
// 
//     @NotNull
//     @Column
//     public Date getSubmitTime() {
//         return submitTime;
//     }
// 
//     public void setSubmitTime(Date submitTime) {
//         this.submitTime = submitTime;
//     }
// 
//     @OneToOne(fetch = FetchType.EAGER)
//     public Category getCategory() {
//         return category;
//     }
// 
//     public void setCategory(Category category) {
//         this.category = category;
//     }
// 
//     @NotNull
//     @Column
//     public Status getStatus() {
//         return status;
//     }
// 
//     public void setStatus(Status status) {
//         this.status = status;
//     }
// 
//     @Column
//     public Date getScheduledTime() {
//         return scheduledTime;
//     }
// 
//     public void setScheduledTime(Date scheduledTime) {
//         this.scheduledTime = scheduledTime;
//     }
// 
//     @Column
//     public Date getCompletionTime() {
//         return completionTime;
//     }
// 
//     public void setCompletionTime(Date completionTime) {
//         this.completionTime = completionTime;
//     }
// 
//     @Column
//     public Integer getRetryCount() {
//         return retryCount;
//     }
// 
//     public void setRetryCount(Integer retryCount) {
//         this.retryCount = retryCount;
//     }
// 
//     @Override
//     public String toString() {
//         return "Job{" +
//                 "name='" + name + '\'' +
//                 ", metadataJson='" + metadataJson + '\'' +
//                 ", callbackUrl='" + callbackUrl + '\'' +
//                 ", submitTime=" + submitTime +
//                 ", status=" + status +
//                 ", scheduledTime=" + scheduledTime +
//                 ", completionTime=" + completionTime +
//                 ", retryCount=" + retryCount +
//                 ", category=" + category +
//                 '}';
//     }
// }
// 
// Path: src/main/java/yourwebproject2/model/entity/helper/CategoryPriorityComparator.java
// public class CategoryPriorityComparator implements Comparator<Job> {
// 
//     /**
//      * Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as
//      * the first argument is less than, equal to, or greater than the second.
//      *
//      * @param o1
//      * @param o2
//      * @return
//      */
//     @Override
//     public int compare(Job o1, Job o2) {
//         // ordering of priority is 1... 2... 3.... N...., where 1 is higher
//         if(o1.getCategory().getPriority() > o2.getCategory().getPriority()) {
//             return 1;
//         } else if(o1.getCategory().getPriority() < o2.getCategory().getPriority()) {
//             return -1;
//         } else {
//             return 0;
//         }
//     }
// }
// 
// Path: src/main/java/yourwebproject2/service/JobService.java
// public interface JobService extends BaseService<Job, Long> {
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchNewJobsToBeScheduledForExecutionPerPriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchFailedJobsToBeScheduledForExecutionPerPriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchNewJobsToBeScheduledForExecutionPerSubmissionTimePriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchFailedJobsToBeScheduledForExecutionPerSubmissionTimePriority(int count);
// }


import yourwebproject2.model.entity.Job;
import yourwebproject2.model.entity.helper.CategoryPriorityComparator;
import yourwebproject2.service.JobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
package yourwebproject2.core;



/**
 * Created by Y.Kamesh on 8/5/2015.
 */
public class NewJobSchedulingWorker extends AbstractJobSchedulingWorker {
    private static Logger LOG = LoggerFactory.getLogger(NewJobSchedulingWorker.class);

    @Autowired
    private JobService jobService;

    private ExecutorService executorService = Executors.newFixedThreadPool(50);

    /**
     * Runs every five minutes.
     */
    @Scheduled(initialDelay = 5000L, fixedRate = 5 * 60 * 1000L)
    public void scheduleNewJobsForExecution() {
        LOG.info("Fetching new jobs as per category and submit time priority...");
        List<Job> newJobs = jobService.fetchNewJobsToBeScheduledForExecutionPerSubmissionTimePriority(10);
        LOG.info("Fetched Jobs Count: "+newJobs.size());
// Path: src/main/java/yourwebproject2/model/entity/Job.java
// @Entity
// @Table(indexes = {  @Index(name="name_idx", columnList = "name", unique = true),
//         @Index(name="status_idx", columnList = "status"),
//         @Index(name="category_idx", columnList = "category")})
// public class Job extends JPAEntity<Long> {
//     public enum Status {
//         NEW, EXECUTING, PRIORITIZED, FAILED, RETRYING, SUCCESSFUL
//     }
// 
//     private String name;
//     private String metadataJson;
//     private String callbackUrl;
//     private Date submitTime;
//     private Status status;
//     private Date scheduledTime;
//     private Date completionTime;
//     private Integer retryCount;
//     private Category category;
// 
//     @NotNull @NotBlank
//     @Column
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     @Column
//     public String getCallbackUrl() {
//         return callbackUrl;
//     }
// 
//     public void setCallbackUrl(String callbackUrl) {
//         this.callbackUrl = callbackUrl;
//     }
// 
//     @Column
//     public String getMetadataJson() {
//         return metadataJson;
//     }
// 
//     public void setMetadataJson(String metadataJson) {
//         this.metadataJson = metadataJson;
//     }
// 
//     @NotNull
//     @Column
//     public Date getSubmitTime() {
//         return submitTime;
//     }
// 
//     public void setSubmitTime(Date submitTime) {
//         this.submitTime = submitTime;
//     }
// 
//     @OneToOne(fetch = FetchType.EAGER)
//     public Category getCategory() {
//         return category;
//     }
// 
//     public void setCategory(Category category) {
//         this.category = category;
//     }
// 
//     @NotNull
//     @Column
//     public Status getStatus() {
//         return status;
//     }
// 
//     public void setStatus(Status status) {
//         this.status = status;
//     }
// 
//     @Column
//     public Date getScheduledTime() {
//         return scheduledTime;
//     }
// 
//     public void setScheduledTime(Date scheduledTime) {
//         this.scheduledTime = scheduledTime;
//     }
// 
//     @Column
//     public Date getCompletionTime() {
//         return completionTime;
//     }
// 
//     public void setCompletionTime(Date completionTime) {
//         this.completionTime = completionTime;
//     }
// 
//     @Column
//     public Integer getRetryCount() {
//         return retryCount;
//     }
// 
//     public void setRetryCount(Integer retryCount) {
//         this.retryCount = retryCount;
//     }
// 
//     @Override
//     public String toString() {
//         return "Job{" +
//                 "name='" + name + '\'' +
//                 ", metadataJson='" + metadataJson + '\'' +
//                 ", callbackUrl='" + callbackUrl + '\'' +
//                 ", submitTime=" + submitTime +
//                 ", status=" + status +
//                 ", scheduledTime=" + scheduledTime +
//                 ", completionTime=" + completionTime +
//                 ", retryCount=" + retryCount +
//                 ", category=" + category +
//                 '}';
//     }
// }
// 
// Path: src/main/java/yourwebproject2/model/entity/helper/CategoryPriorityComparator.java
// public class CategoryPriorityComparator implements Comparator<Job> {
// 
//     /**
//      * Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as
//      * the first argument is less than, equal to, or greater than the second.
//      *
//      * @param o1
//      * @param o2
//      * @return
//      */
//     @Override
//     public int compare(Job o1, Job o2) {
//         // ordering of priority is 1... 2... 3.... N...., where 1 is higher
//         if(o1.getCategory().getPriority() > o2.getCategory().getPriority()) {
//             return 1;
//         } else if(o1.getCategory().getPriority() < o2.getCategory().getPriority()) {
//             return -1;
//         } else {
//             return 0;
//         }
//     }
// }
// 
// Path: src/main/java/yourwebproject2/service/JobService.java
// public interface JobService extends BaseService<Job, Long> {
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchNewJobsToBeScheduledForExecutionPerPriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchFailedJobsToBeScheduledForExecutionPerPriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchNewJobsToBeScheduledForExecutionPerSubmissionTimePriority(int count);
// 
//     /**
//      *
//      * @param count
//      * @return
//      */
//     public List<Job> fetchFailedJobsToBeScheduledForExecutionPerSubmissionTimePriority(int count);
// }


// Path: src/main/java/yourwebproject2/core/NewJobSchedulingWorker.java
import yourwebproject2.model.entity.Job;
import yourwebproject2.model.entity.helper.CategoryPriorityComparator;
import yourwebproject2.service.JobService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

package yourwebproject2.core;



/**
 * Created by Y.Kamesh on 8/5/2015.
 */
public class NewJobSchedulingWorker extends AbstractJobSchedulingWorker {
    private static Logger LOG = LoggerFactory.getLogger(NewJobSchedulingWorker.class);

    @Autowired
    private JobService jobService;

    private ExecutorService executorService = Executors.newFixedThreadPool(50);

    /**
     * Runs every five minutes.
     */
    @Scheduled(initialDelay = 5000L, fixedRate = 5 * 60 * 1000L)
    public void scheduleNewJobsForExecution() {
        LOG.info("Fetching new jobs as per category and submit time priority...");
        List<Job> newJobs = jobService.fetchNewJobsToBeScheduledForExecutionPerSubmissionTimePriority(10);
        LOG.info("Fetched Jobs Count: "+newJobs.size());
        Collections.sort(newJobs, new CategoryPriorityComparator());