Skip to content

v0.2.50..v0.2.51 changeset JobsStatusesManagerImpl.java

Garret Voltz edited this page Jan 15, 2020 · 1 revision
diff --git a/hoot-services/src/main/java/hoot/services/jobs/JobsStatusesManagerImpl.java b/hoot-services/src/main/java/hoot/services/jobs/JobsStatusesManagerImpl.java
index f09cedb..dc400da 100644
--- a/hoot-services/src/main/java/hoot/services/jobs/JobsStatusesManagerImpl.java
+++ b/hoot-services/src/main/java/hoot/services/jobs/JobsStatusesManagerImpl.java
@@ -30,7 +30,8 @@ import static hoot.services.job.JobStatus.RUNNING;
 import static hoot.services.models.db.QJobStatus.jobStatus;
 import static hoot.services.utils.DbUtils.createQuery;
 
-import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -38,7 +39,13 @@ import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import com.querydsl.core.types.OrderSpecifier;
+import com.querydsl.core.types.Predicate;
+import com.querydsl.core.types.dsl.Expressions;
+import com.querydsl.core.types.dsl.NumberExpression;
+
 import hoot.services.controllers.job.JobStatusResponse;
+import hoot.services.controllers.jobs.JobHistory;
 import hoot.services.job.JobType;
 import hoot.services.models.db.JobStatus;
 import hoot.services.models.db.Users;
@@ -48,57 +55,88 @@ import hoot.services.models.db.Users;
 public class JobsStatusesManagerImpl implements JobsStatusesManager {
     public JobsStatusesManagerImpl() {}
 
+
     @Override
-    public List<JobStatusResponse> getRecentJobs(Users user, int limit) {
-        long past12 = System.currentTimeMillis() - 43200000 /* 12 hours */;
-        List<JobStatus> recentJobs = createQuery()
-                .select(jobStatus)
-                .from(jobStatus)
-                .where((jobStatus.start.after(new Timestamp(past12)).and(jobStatus.userId.eq(user.getId())))
-                        .or(jobStatus.status.eq(RUNNING.ordinal())))
-                .orderBy(jobStatus.start.desc())
-                .fetch();
-        if(recentJobs.size() < limit) {
-            recentJobs = createQuery().select(jobStatus)
-                    .from(jobStatus)
-                    .where(jobStatus.userId.eq(user.getId())
-                            .or(jobStatus.status.eq(RUNNING.ordinal()))
-                    )
-                    .orderBy(jobStatus.start.desc()).limit(limit).fetch();
+    public JobHistory getJobsHistory(Users user, String sort, long offset, long limit, String type, String status) throws IllegalArgumentException {
+        OrderSpecifier<?> sorter = jobStatus.start.desc();
+        List<Integer> types = new ArrayList<>();
+        List<Integer> statuses = new ArrayList<>();
+
+        //Hack, but no other way I could find to get timestamp as epoch with query dsl
+        //so this calculates the duration between start and end timestamps in milliseconds
+        NumberExpression<Long> duration = jobStatus.end.dayOfYear().castToNum(Long.class).multiply(Expressions.constant(86400000d))
+                .add(jobStatus.end.hour().castToNum(Long.class).multiply(Expressions.constant(3600000d)))
+                .add(jobStatus.end.minute().castToNum(Long.class).multiply(Expressions.constant(60000d)))
+                .add(jobStatus.end.second().castToNum(Long.class).multiply(Expressions.constant(1000d)))
+                .add(jobStatus.end.milliSecond().castToNum(Long.class))
+                .subtract(
+                        jobStatus.start.dayOfYear().castToNum(Long.class).multiply(Expressions.constant(86400000d))
+                        .add(jobStatus.start.hour().castToNum(Long.class).multiply(Expressions.constant(3600000d)))
+                        .add(jobStatus.start.minute().castToNum(Long.class).multiply(Expressions.constant(60000d)))
+                        .add(jobStatus.start.second().castToNum(Long.class).multiply(Expressions.constant(1000d)))
+                        .add(jobStatus.start.milliSecond().castToNum(Long.class))
+                );
+
+        switch (sort) {
+        case "+type":
+            sorter = jobStatus.jobType.asc();
+            break;
+        case "-type":
+            sorter = jobStatus.jobType.desc();
+            break;
+        case "+status":
+            sorter = jobStatus.status.asc();
+            break;
+        case "-status":
+            sorter = jobStatus.status.desc();
+            break;
+        case "+duration":
+            sorter = duration.asc();
+            break;
+        case "-duration":
+            sorter = duration.desc();
+            break;
+        case "+start":
+            sorter = jobStatus.start.asc();
+            break;
+        case "-start":
+        default:
+            sorter = jobStatus.start.desc();
+            break;
         }
 
+        if (!type.isEmpty()) {
+            types = Arrays.stream(type.split(","))
+                .map(String::toUpperCase)
+                .map(JobType::valueOf)
+                .map(JobType::ordinal)
+                .collect(Collectors.toList());
+        }
 
-        //format jobs
-        return recentJobs.stream().map(j -> {
-            JobStatusResponse response = new JobStatusResponse();
-            response.setJobId(j.getJobId());
-            response.setJobType(JobType.fromInteger(
-                    (j.getJobType() != null) ? j.getJobType() : JobType.UNKNOWN.ordinal()
-                ).toString());
-            response.setUserId(j.getUserId());
-            response.setMapId(j.getResourceId());
-            response.setStart(j.getStart().getTime());
-            response.setEnd(j.getEnd().getTime());
-            response.setStatus(hoot.services.job.JobStatus.fromInteger(j.getStatus()).toString());
-            response.setPercentComplete(j.getPercentComplete());
+        if (!status.isEmpty()) {
+            statuses = Arrays.stream(status.split(","))
+                .map(String::toUpperCase)
+                .map(hoot.services.job.JobStatus::valueOf)
+                .map(hoot.services.job.JobStatus::ordinal)
+                .collect(Collectors.toList());
+        }
 
-            return response;
-        }).collect(Collectors.toList());
-    }
+        Predicate whereClause = jobStatus.userId.eq(user.getId()) //filter by user
+                .and(jobStatus.status.gt(0)) //filter out running jobs
+                .and((!types.isEmpty()) ? jobStatus.jobType.in(types) : jobStatus.jobType.isNotNull()) //filter by type
+                .and((!statuses.isEmpty()) ? jobStatus.status.in(statuses) : jobStatus.status.isNotNull()) //filter by status
+                ;
 
-    @Override
-    public List<JobStatusResponse> getJobsHistory(Users user) {
         List<JobStatus> jobsHistory = createQuery()
                 .select(jobStatus)
                 .from(jobStatus)
-                .where(jobStatus.userId.eq(user.getId())
-                    .and(jobStatus.status.gt(0)))
-                .orderBy(jobStatus.start.desc())
+                .where(whereClause)
+                .orderBy(sorter)
+                .offset(offset)
+                .limit(limit)
                 .fetch();
 
-
-        //format jobs
-        return jobsHistory.stream().map(j -> {
+        List<JobStatusResponse> jobs = jobsHistory.stream().map(j -> {
             JobStatusResponse response = new JobStatusResponse();
             response.setJobId(j.getJobId());
             response.setJobType(JobType.fromInteger(
@@ -112,7 +150,17 @@ public class JobsStatusesManagerImpl implements JobsStatusesManager {
 
             return response;
         }).collect(Collectors.toList());
+
+        Long total = createQuery()
+                .select(jobStatus)
+                .from(jobStatus)
+                .where(whereClause)
+                .fetchCount();
+
+        //format jobs history
+        return new JobHistory(total, jobs);
     }
+
     @Override
     public List<JobStatusResponse> getRunningJobs() {
         List<JobStatus> runningJobs = createQuery()
Clone this wiki locally