You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by ja...@apache.org on 2016/07/26 17:35:09 UTC

oozie git commit: OOZIE-2520 SortBy filter for ordering the jobs query results (abhishekbafna via jaydeepvishwakarma)

Repository: oozie
Updated Branches:
  refs/heads/master 9ca2aa4f2 -> 9650a728d


OOZIE-2520 SortBy filter for ordering the jobs query results (abhishekbafna via jaydeepvishwakarma)


Project: http://git-wip-us.apache.org/repos/asf/oozie/repo
Commit: http://git-wip-us.apache.org/repos/asf/oozie/commit/9650a728
Tree: http://git-wip-us.apache.org/repos/asf/oozie/tree/9650a728
Diff: http://git-wip-us.apache.org/repos/asf/oozie/diff/9650a728

Branch: refs/heads/master
Commit: 9650a728dde61f83dda452c23ea74fc7bf0c4900
Parents: 9ca2aa4
Author: jvishwakarma <jv...@walmartlabs.com>
Authored: Tue Jul 26 23:04:39 2016 +0530
Committer: jvishwakarma <jv...@walmartlabs.com>
Committed: Tue Jul 26 23:04:39 2016 +0530

----------------------------------------------------------------------
 .../java/org/apache/oozie/cli/OozieCLI.java     |  5 ++-
 .../org/apache/oozie/client/OozieClient.java    | 15 +++++++
 .../org/apache/oozie/CoordinatorEngine.java     |  1 +
 .../main/java/org/apache/oozie/DagEngine.java   |  1 +
 .../jpa/BundleJobInfoGetJPAExecutor.java        | 12 ++++--
 .../executor/jpa/BundleJobQueryExecutor.java    |  2 +-
 .../jpa/CoordJobInfoGetJPAExecutor.java         | 12 ++++--
 .../jpa/WorkflowsJobGetJPAExecutor.java         | 29 +++++++-------
 .../apache/oozie/store/StoreStatusFilter.java   | 21 ++++++++++
 .../org/apache/oozie/util/JobsFilterUtils.java  |  1 +
 .../org/apache/oozie/client/TestOozieCLI.java   | 15 +++++++
 .../jpa/TestBundleJobInfoGetJPAExecutor.java    | 40 +++++++++++++++++++
 .../jpa/TestBundleJobQueryExecutor.java         |  2 +-
 .../jpa/TestCoordJobInfoGetJPAExecutor.java     | 41 +++++++++++++++++++-
 .../jpa/TestWorkflowsJobGetJPAExecutor.java     | 41 ++++++++++++++++++++
 docs/src/site/twiki/DG_CommandLineTool.twiki    |  6 ++-
 docs/src/site/twiki/WebServicesAPI.twiki        |  1 +
 release-log.txt                                 |  1 +
 18 files changed, 219 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/client/src/main/java/org/apache/oozie/cli/OozieCLI.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/oozie/cli/OozieCLI.java b/client/src/main/java/org/apache/oozie/cli/OozieCLI.java
index 01efb48..f1d0f2b 100644
--- a/client/src/main/java/org/apache/oozie/cli/OozieCLI.java
+++ b/client/src/main/java/org/apache/oozie/cli/OozieCLI.java
@@ -455,9 +455,10 @@ public class OozieCLI {
         Option len = new Option(LEN_OPTION, true, "number of jobs (default '100')");
         Option filter = new Option(FILTER_OPTION, true,
                 "user=<U>\\;name=<N>\\;group=<G>\\;status=<S>\\;frequency=<F>\\;unit=<M>" +
-                        "\\;startcreatedtime=<SC>\\;endcreatedtime=<EC> " +
+                        "\\;startcreatedtime=<SC>\\;endcreatedtime=<EC> \\;sortBy=<SB>" +
                         "(valid unit values are 'months', 'days', 'hours' or 'minutes'. " +
-                        "startcreatedtime, endcreatedtime: time of format yyyy-MM-dd'T'HH:mm'Z')");
+                        "startcreatedtime, endcreatedtime: time of format yyyy-MM-dd'T'HH:mm'Z'. " +
+                        "valid values for sortBy are 'createdTime' or 'lastModifiedTime'.)");
         Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (same as passing your time zone to -" +
                 TIME_ZONE_OPTION + "). Overrides -" + TIME_ZONE_OPTION + " option");
         Option kill = new Option(KILL_OPTION, false, "bulk kill operation");

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/client/src/main/java/org/apache/oozie/client/OozieClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/oozie/client/OozieClient.java b/client/src/main/java/org/apache/oozie/client/OozieClient.java
index 2ffbd6a..eee2d63 100644
--- a/client/src/main/java/org/apache/oozie/client/OozieClient.java
+++ b/client/src/main/java/org/apache/oozie/client/OozieClient.java
@@ -186,6 +186,21 @@ public class OozieClient {
 
     public static final String OOZIE_SUSPEND_ON_NODES = "oozie.suspend.on.nodes";
 
+    public static final String FILTER_SORT_BY = "sortby";
+
+    public enum SORT_BY {
+        createdTime("createdTimestamp"), lastModifiedTime("lastModifiedTimestamp");
+        private final String fullname;
+
+        SORT_BY(String fullname) {
+            this.fullname = fullname;
+        }
+
+        public String getFullname() {
+            return fullname;
+        }
+    }
+
     public static enum SYSTEM_MODE {
         NORMAL, NOWEBSERVICE, SAFEMODE
     }

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/CoordinatorEngine.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/CoordinatorEngine.java b/core/src/main/java/org/apache/oozie/CoordinatorEngine.java
index 79d0d97..2301908 100644
--- a/core/src/main/java/org/apache/oozie/CoordinatorEngine.java
+++ b/core/src/main/java/org/apache/oozie/CoordinatorEngine.java
@@ -610,6 +610,7 @@ public class CoordinatorEngine extends BaseEngine {
         FILTER_NAMES.add(OozieClient.FILTER_ID);
         FILTER_NAMES.add(OozieClient.FILTER_FREQUENCY);
         FILTER_NAMES.add(OozieClient.FILTER_UNIT);
+        FILTER_NAMES.add(OozieClient.FILTER_SORT_BY);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/DagEngine.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/DagEngine.java b/core/src/main/java/org/apache/oozie/DagEngine.java
index fd83360..01aeddf 100644
--- a/core/src/main/java/org/apache/oozie/DagEngine.java
+++ b/core/src/main/java/org/apache/oozie/DagEngine.java
@@ -474,6 +474,7 @@ public class DagEngine extends BaseEngine {
         FILTER_NAMES.add(OozieClient.FILTER_ID);
         FILTER_NAMES.add(OozieClient.FILTER_CREATED_TIME_START);
         FILTER_NAMES.add(OozieClient.FILTER_CREATED_TIME_END);
+        FILTER_NAMES.add(OozieClient.FILTER_SORT_BY);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobInfoGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobInfoGetJPAExecutor.java b/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobInfoGetJPAExecutor.java
index 4b631c1..dace4e8 100644
--- a/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobInfoGetJPAExecutor.java
+++ b/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobInfoGetJPAExecutor.java
@@ -45,6 +45,7 @@ import org.apache.openjpa.persistence.jdbc.ResultSetType;
  */
 public class BundleJobInfoGetJPAExecutor implements JPAExecutor<BundleJobInfo> {
 
+    public static final String DEFAULT_ORDER_BY = " order by w.createdTimestamp desc ";
     private Map<String, List<String>> filter;
     private int start = 1;
     private int len = 50;
@@ -81,27 +82,30 @@ public class BundleJobInfoGetJPAExecutor implements JPAExecutor<BundleJobInfo> {
         List<String> colArray = new ArrayList<String>();
         List<String> valArray = new ArrayList<String>();
         StringBuilder sb = new StringBuilder("");
+        String orderBy = DEFAULT_ORDER_BY;
 
         StoreStatusFilter.filter(filter, orArray, colArray, valArray, sb, StoreStatusFilter.bundleSeletStr,
                                  StoreStatusFilter.bundleCountStr);
+        orderBy = StoreStatusFilter.getSortBy(filter, orderBy);
 
         int realLen = 0;
 
         Query q = null;
         Query qTotal = null;
-        if (orArray.size() == 0) {
+        if (orArray.size() == 0 && orderBy.equals(DEFAULT_ORDER_BY)) {
             q = em.createNamedQuery("GET_BUNDLE_JOBS_COLUMNS");
             q.setFirstResult(start - 1);
             q.setMaxResults(len);
             qTotal = em.createNamedQuery("GET_BUNDLE_JOBS_COUNT");
         }
         else {
-            StringBuilder sbTotal = new StringBuilder(sb);
-            sb.append(" order by w.createdTimestamp desc ");
+            sb = sb.toString().trim().length() == 0 ? sb.append(StoreStatusFilter.bundleSeletStr) : sb;
+            String sbTotal = sb.toString();
+            sb.append(orderBy);
             q = em.createQuery(sb.toString());
             q.setFirstResult(start - 1);
             q.setMaxResults(len);
-            qTotal = em.createQuery(sbTotal.toString().replace(StoreStatusFilter.bundleSeletStr,
+            qTotal = em.createQuery(sbTotal.replace(StoreStatusFilter.bundleSeletStr,
                                                                           StoreStatusFilter.bundleCountStr));
         }
 

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobQueryExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobQueryExecutor.java b/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobQueryExecutor.java
index bfd1dae..cc554d6 100644
--- a/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobQueryExecutor.java
+++ b/core/src/main/java/org/apache/oozie/executor/jpa/BundleJobQueryExecutor.java
@@ -79,7 +79,7 @@ public class BundleJobQueryExecutor extends QueryExecutor<BundleJobBean, BundleJ
                 query.setParameter("origJobXml", bjBean.getOrigJobXmlBlob());
                 query.setParameter("startTime", bjBean.getstartTimestamp());
                 query.setParameter("status", bjBean.getStatus().toString());
-                query.setParameter("timeUnit", bjBean.getTimeUnit());
+                query.setParameter("timeUnit", bjBean.getTimeUnitStr());
                 query.setParameter("pending", bjBean.isPending() ? 1 : 0);
                 query.setParameter("id", bjBean.getId());
                 break;

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/executor/jpa/CoordJobInfoGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/executor/jpa/CoordJobInfoGetJPAExecutor.java b/core/src/main/java/org/apache/oozie/executor/jpa/CoordJobInfoGetJPAExecutor.java
index c924f44..8fcb1e6 100644
--- a/core/src/main/java/org/apache/oozie/executor/jpa/CoordJobInfoGetJPAExecutor.java
+++ b/core/src/main/java/org/apache/oozie/executor/jpa/CoordJobInfoGetJPAExecutor.java
@@ -44,6 +44,7 @@ import org.apache.openjpa.persistence.jdbc.ResultSetType;
  */
 public class CoordJobInfoGetJPAExecutor implements JPAExecutor<CoordinatorJobInfo> {
 
+    public static final String DEFAULT_ORDER_BY = " order by w.createdTimestamp desc ";
     private Map<String, List<String>> filter;
     private int start = 1;
     private int len = 50;
@@ -67,27 +68,30 @@ public class CoordJobInfoGetJPAExecutor implements JPAExecutor<CoordinatorJobInf
         List<String> colArray = new ArrayList<String>();
         List<String> valArray = new ArrayList<String>();
         StringBuilder sb = new StringBuilder("");
+        String orderBy = DEFAULT_ORDER_BY;
 
         StoreStatusFilter.filter(filter, orArray, colArray, valArray, sb, StoreStatusFilter.coordSeletStr,
                                  StoreStatusFilter.coordCountStr);
 
+        orderBy = StoreStatusFilter.getSortBy(filter, orderBy);
         int realLen = 0;
 
         Query q = null;
         Query qTotal = null;
-        if (orArray.size() == 0) {
+        if (orArray.size() == 0 && orderBy.equals(DEFAULT_ORDER_BY)) {
             q = em.createNamedQuery("GET_COORD_JOBS_COLUMNS");
             q.setFirstResult(start - 1);
             q.setMaxResults(len);
             qTotal = em.createNamedQuery("GET_COORD_JOBS_COUNT");
         }
         else {
-            StringBuilder sbTotal = new StringBuilder(sb);
-            sb.append(" order by w.createdTimestamp desc ");
+            sb = sb.toString().trim().length() == 0 ? sb.append(StoreStatusFilter.coordSeletStr) : sb;
+            String sbTotal = sb.toString();
+            sb.append(orderBy);
             q = em.createQuery(sb.toString());
             q.setFirstResult(start - 1);
             q.setMaxResults(len);
-            qTotal = em.createQuery(sbTotal.toString().replace(StoreStatusFilter.coordSeletStr,
+            qTotal = em.createQuery(sbTotal.replace(StoreStatusFilter.coordSeletStr,
                                                                           StoreStatusFilter.coordCountStr));
         }
 

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/executor/jpa/WorkflowsJobGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/executor/jpa/WorkflowsJobGetJPAExecutor.java b/core/src/main/java/org/apache/oozie/executor/jpa/WorkflowsJobGetJPAExecutor.java
index 00d2263..5cde60e 100644
--- a/core/src/main/java/org/apache/oozie/executor/jpa/WorkflowsJobGetJPAExecutor.java
+++ b/core/src/main/java/org/apache/oozie/executor/jpa/WorkflowsJobGetJPAExecutor.java
@@ -29,12 +29,12 @@ import java.util.Map;
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.oozie.ErrorCode;
 import org.apache.oozie.WorkflowJobBean;
 import org.apache.oozie.WorkflowsInfo;
 import org.apache.oozie.client.OozieClient;
 import org.apache.oozie.client.WorkflowJob.Status;
+import org.apache.oozie.store.StoreStatusFilter;
 import org.apache.oozie.util.DateUtils;
 import org.apache.oozie.util.XLog;
 import org.apache.openjpa.persistence.OpenJPAPersistence;
@@ -49,6 +49,7 @@ public class WorkflowsJobGetJPAExecutor implements JPAExecutor<WorkflowsInfo> {
     private static final String seletStr = "Select w.id, w.appName, w.statusStr, w.run, w.user, w.group, w.createdTimestamp, "
             + "w.startTimestamp, w.lastModifiedTimestamp, w.endTimestamp, w.externalId, w.parentId from WorkflowJobBean w";
     private static final String countStr = "Select count(w) from WorkflowJobBean w";
+    public static final String DEFAULT_ORDER_BY = " order by w.createdTimestamp desc ";
 
     private final Map<String, List<String>> filter;
     private final int start;
@@ -77,6 +78,7 @@ public class WorkflowsJobGetJPAExecutor implements JPAExecutor<WorkflowsInfo> {
         List<String> colArray = new ArrayList<String>();
         List<Object> valArray = new ArrayList<Object>();
         StringBuilder sb = new StringBuilder("");
+        String orderBy = DEFAULT_ORDER_BY;
         boolean isStatus = false;
         boolean isAppName = false;
         boolean isUser = false;
@@ -278,29 +280,30 @@ public class WorkflowsJobGetJPAExecutor implements JPAExecutor<WorkflowsInfo> {
                 }
             }
         }
+
+        orderBy = StoreStatusFilter.getSortBy(filter, orderBy);
         int realLen = 0;
 
         Query q = null;
         Query qTotal = null;
-        if (orArray.size() == 0) {
+        if (orArray.size() == 0 && orderBy.equals(DEFAULT_ORDER_BY)) {
             q = em.createNamedQuery("GET_WORKFLOWS_COLUMNS");
             q.setFirstResult(start - 1);
             q.setMaxResults(len);
             qTotal = em.createNamedQuery("GET_WORKFLOWS_COUNT");
         }
         else {
-            if (orArray.size() > 0) {
-                StringBuilder sbTotal = new StringBuilder(sb);
-                sb.append(" order by w.createdTimestamp desc ");
-                q = em.createQuery(sb.toString());
-                q.setFirstResult(start - 1);
-                q.setMaxResults(len);
-                qTotal = em.createQuery(sbTotal.toString().replace(seletStr, countStr));
+            sb = sb.toString().trim().length() == 0 ? sb.append(seletStr) : sb;
+            String sbTotal = sb.toString();
+            sb.append(orderBy);
+            q = em.createQuery(sb.toString());
+            q.setFirstResult(start - 1);
+            q.setMaxResults(len);
+            qTotal = em.createQuery(sbTotal.replace(seletStr, countStr));
 
-                for (int i = 0; i < orArray.size(); i++) {
-                    q.setParameter(colArray.get(i), valArray.get(i));
-                    qTotal.setParameter(colArray.get(i), valArray.get(i));
-                }
+            for (int i = 0; i < orArray.size(); i++) {
+                q.setParameter(colArray.get(i), valArray.get(i));
+                qTotal.setParameter(colArray.get(i), valArray.get(i));
             }
         }
 

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/store/StoreStatusFilter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/store/StoreStatusFilter.java b/core/src/main/java/org/apache/oozie/store/StoreStatusFilter.java
index d442aa8..ebdbaa4 100644
--- a/core/src/main/java/org/apache/oozie/store/StoreStatusFilter.java
+++ b/core/src/main/java/org/apache/oozie/store/StoreStatusFilter.java
@@ -21,7 +21,9 @@ package org.apache.oozie.store;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.oozie.ErrorCode;
 import org.apache.oozie.client.OozieClient;
+import org.apache.oozie.executor.jpa.JPAExecutorException;
 import org.apache.oozie.util.XLog;
 
 public class StoreStatusFilter {
@@ -252,4 +254,23 @@ public class StoreStatusFilter {
             }
         }
     }
+
+    public static String getSortBy(Map<String, List<String>> filter, String sortByStr) throws JPAExecutorException {
+        if (filter.containsKey(OozieClient.FILTER_SORT_BY)) {
+            List<String> values = filter.get(OozieClient.FILTER_SORT_BY);
+            if (values.size() > 1) {
+                throw new JPAExecutorException(ErrorCode.E0302,
+                        "cannot specify multiple sortby parameter");
+            }
+            String value = values.get(0);
+            for (OozieClient.SORT_BY sortBy : OozieClient.SORT_BY.values()) {
+                if (sortBy.toString().equalsIgnoreCase(value)) {
+                    value = sortBy.getFullname();
+                    sortByStr = " order by w.".concat(value).concat(" desc ");
+                    break;
+                }
+            }
+        }
+        return sortByStr;
+    }
 }

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/main/java/org/apache/oozie/util/JobsFilterUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/oozie/util/JobsFilterUtils.java b/core/src/main/java/org/apache/oozie/util/JobsFilterUtils.java
index 52d3e9d..90c772f 100644
--- a/core/src/main/java/org/apache/oozie/util/JobsFilterUtils.java
+++ b/core/src/main/java/org/apache/oozie/util/JobsFilterUtils.java
@@ -43,6 +43,7 @@ public class JobsFilterUtils {
         FILTER_NAMES.add(OozieClient.FILTER_GROUP);
         FILTER_NAMES.add(OozieClient.FILTER_STATUS);
         FILTER_NAMES.add(OozieClient.FILTER_ID);
+        FILTER_NAMES.add(OozieClient.FILTER_SORT_BY);
     }
 
     public static Map<String, List<String>> parseFilter(String filter) throws ServletException{

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/test/java/org/apache/oozie/client/TestOozieCLI.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/client/TestOozieCLI.java b/core/src/test/java/org/apache/oozie/client/TestOozieCLI.java
index 54bfc16..6529bfa 100644
--- a/core/src/test/java/org/apache/oozie/client/TestOozieCLI.java
+++ b/core/src/test/java/org/apache/oozie/client/TestOozieCLI.java
@@ -905,6 +905,21 @@ public class TestOozieCLI extends DagServletTestCase {
                 assertEquals(0, new OozieCLI().run(args));
                 assertEquals(RestConstants.JOBS_FILTER_PARAM, MockDagEngineService.did);
 
+                args = new String[] { "jobs", "-filter",
+                        "sortby=lastmodifiedtime", "-oozie", oozieUrl };
+                assertEquals(0, new OozieCLI().run(args));
+                assertEquals(RestConstants.JOBS_FILTER_PARAM, MockDagEngineService.did);
+
+                args = new String[] { "jobs", "-filter",
+                        "sortby=lastmodifiedtime", "-jobtype", "coord", "-oozie", oozieUrl };
+                assertEquals(0, new OozieCLI().run(args));
+                assertEquals(RestConstants.JOBS_FILTER_PARAM, MockDagEngineService.did);
+
+                args = new String[] { "jobs", "-filter",
+                        "sortby=lastmodifiedtime", "-jobtype", "bundle", "-oozie", oozieUrl };
+                assertEquals(0, new OozieCLI().run(args));
+                assertEquals(RestConstants.JOBS_FILTER_PARAM, MockDagEngineService.did);
+
                 return null;
             }
         });

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobInfoGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobInfoGetJPAExecutor.java b/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobInfoGetJPAExecutor.java
index 5714040..14bbbbb 100644
--- a/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobInfoGetJPAExecutor.java
+++ b/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobInfoGetJPAExecutor.java
@@ -30,6 +30,7 @@ import org.apache.oozie.client.OozieClient;
 import org.apache.oozie.service.JPAService;
 import org.apache.oozie.service.Services;
 import org.apache.oozie.test.XDataTestCase;
+import org.apache.oozie.util.DateUtils;
 
 public class TestBundleJobInfoGetJPAExecutor extends XDataTestCase {
     Services services;
@@ -148,4 +149,43 @@ public class TestBundleJobInfoGetJPAExecutor extends XDataTestCase {
         assertEquals(ret.getBundleJobs().size(), 1);
     }
 
+    public void testBundleJobsSortBy() throws Exception {
+        BundleJobBean bundleJob1 = addRecordToBundleJobTable(Job.Status.PREP, false);
+        BundleJobBean bundleJob2 = addRecordToBundleJobTable(Job.Status.RUNNING, false);
+
+        bundleJob1.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-04T10:00Z"));
+        bundleJob1.setCreatedTime(DateUtils.parseDateUTC("2012-01-03T10:00Z"));
+        BundleJobQueryExecutor.getInstance().executeUpdate(BundleJobQueryExecutor.BundleJobQuery.UPDATE_BUNDLE_JOB, bundleJob1);
+
+        bundleJob2.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-05T10:00Z"));
+        bundleJob2.setCreatedTime(DateUtils.parseDateUTC("2012-01-02T10:00Z"));
+        BundleJobQueryExecutor.getInstance().executeUpdate(BundleJobQueryExecutor.BundleJobQuery.UPDATE_BUNDLE_JOB, bundleJob2);
+
+        JPAService jpaService = Services.get().get(JPAService.class);
+        assertNotNull(jpaService);
+        Map<String, List<String>> filter = new HashMap<String, List<String>>();
+        List<String> list = new ArrayList<String>();
+        list.add("lastmodifiedTime");
+        filter.put(OozieClient.FILTER_SORT_BY, list);
+
+        BundleJobInfoGetJPAExecutor bundleInfoGetCmd = new BundleJobInfoGetJPAExecutor(filter, 1, 20);
+        BundleJobInfo ret = jpaService.execute(bundleInfoGetCmd);
+        assertNotNull(ret);
+        assertEquals(2, ret.getBundleJobs().size());
+        compareBundleJobs(bundleJob2, ret.getBundleJobs().get(0));
+        //test the default behavior
+        filter.clear();
+        list.clear();
+        bundleInfoGetCmd = new BundleJobInfoGetJPAExecutor(filter, 1, 20);
+        ret = jpaService.execute(bundleInfoGetCmd);
+        assertNotNull(ret);
+        assertEquals(2, ret.getBundleJobs().size());
+        compareBundleJobs(bundleJob1, ret.getBundleJobs().get(0));
+    }
+
+    private void compareBundleJobs(BundleJobBean bundleJobBean, BundleJobBean retBundleJobBean) {
+        assertEquals(bundleJobBean.getId(), retBundleJobBean.getId());
+        assertEquals(bundleJobBean.getCreatedTime(), retBundleJobBean.getCreatedTime());
+        assertEquals(bundleJobBean.getStatusStr(), retBundleJobBean.getStatusStr());
+    }
 }

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobQueryExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobQueryExecutor.java b/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobQueryExecutor.java
index 97cbb7f..df652ce 100644
--- a/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobQueryExecutor.java
+++ b/core/src/test/java/org/apache/oozie/executor/jpa/TestBundleJobQueryExecutor.java
@@ -65,7 +65,7 @@ public class TestBundleJobQueryExecutor extends XDataTestCase {
         assertEquals(query.getParameterValue("origJobXml"), bean.getOrigJobXmlBlob());
         assertEquals(query.getParameterValue("startTime"), bean.getstartTimestamp());
         assertEquals(query.getParameterValue("status"), bean.getStatus().toString());
-        assertEquals(query.getParameterValue("timeUnit"), bean.getTimeUnit());
+        assertEquals(query.getParameterValue("timeUnit"), bean.getTimeUnitStr());
         assertEquals(query.getParameterValue("pending"), bean.getPending());
         assertEquals(query.getParameterValue("id"), bean.getId());
 

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/test/java/org/apache/oozie/executor/jpa/TestCoordJobInfoGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/executor/jpa/TestCoordJobInfoGetJPAExecutor.java b/core/src/test/java/org/apache/oozie/executor/jpa/TestCoordJobInfoGetJPAExecutor.java
index 5335213..e98b146 100644
--- a/core/src/test/java/org/apache/oozie/executor/jpa/TestCoordJobInfoGetJPAExecutor.java
+++ b/core/src/test/java/org/apache/oozie/executor/jpa/TestCoordJobInfoGetJPAExecutor.java
@@ -27,10 +27,10 @@ import org.apache.oozie.CoordinatorJobBean;
 import org.apache.oozie.CoordinatorJobInfo;
 import org.apache.oozie.client.CoordinatorJob;
 import org.apache.oozie.client.OozieClient;
-import org.apache.oozie.local.LocalOozie;
 import org.apache.oozie.service.JPAService;
 import org.apache.oozie.service.Services;
 import org.apache.oozie.test.XDataTestCase;
+import org.apache.oozie.util.DateUtils;
 
 public class TestCoordJobInfoGetJPAExecutor extends XDataTestCase {
     Services services;
@@ -211,4 +211,43 @@ public class TestCoordJobInfoGetJPAExecutor extends XDataTestCase {
         assertNotNull(ret);
         assertEquals(ret.getCoordJobs().size(), 3);
     }
+
+    public void testCoordGetJobsSortBy() throws Exception {
+        CoordinatorJobBean coordinatorJob1 = addRecordToCoordJobTable(CoordinatorJob.Status.FAILED, false, false);
+        CoordinatorJobBean coordinatorJob2 = addRecordToCoordJobTable(CoordinatorJob.Status.RUNNING, false, false);
+
+        coordinatorJob1.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-04T10:00Z"));
+        coordinatorJob1.setCreatedTime(DateUtils.parseDateUTC("2012-01-03T10:00Z"));
+        CoordJobQueryExecutor.getInstance().executeUpdate(CoordJobQueryExecutor.CoordJobQuery.UPDATE_COORD_JOB, coordinatorJob1);
+
+        coordinatorJob2.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-05T10:00Z"));
+        coordinatorJob2.setCreatedTime(DateUtils.parseDateUTC("2012-01-02T10:00Z"));
+        CoordJobQueryExecutor.getInstance().executeUpdate(CoordJobQueryExecutor.CoordJobQuery.UPDATE_COORD_JOB, coordinatorJob2);
+
+        JPAService jpaService = Services.get().get(JPAService.class);
+        assertNotNull(jpaService);
+        Map<String, List<String>> filter = new HashMap<String, List<String>>();
+        List<String> list = new ArrayList<String>();
+        list.add("lastmodifiedtime");
+        filter.put(OozieClient.FILTER_SORT_BY, list);
+        CoordJobInfoGetJPAExecutor coordInfoGetCmd = new CoordJobInfoGetJPAExecutor(filter, 1, 20);
+        CoordinatorJobInfo ret = jpaService.execute(coordInfoGetCmd);
+        assertNotNull(ret);
+        assertEquals(2, ret.getCoordJobs().size());
+        compareCoordJobs(coordinatorJob2, ret.getCoordJobs().get(0));
+        //test default behavior
+        filter.clear();
+        list.clear();
+        coordInfoGetCmd = new CoordJobInfoGetJPAExecutor(filter, 1, 20);
+        ret = jpaService.execute(coordInfoGetCmd);
+        assertNotNull(ret);
+        assertEquals(2, ret.getCoordJobs().size());
+        compareCoordJobs(coordinatorJob1, ret.getCoordJobs().get(0));
+    }
+
+    private void compareCoordJobs(CoordinatorJobBean coordBean, CoordinatorJobBean retCoordBean) {
+        assertEquals(coordBean.getId(), retCoordBean.getId());
+        assertEquals(coordBean.getStatusStr(), retCoordBean.getStatusStr());
+        assertEquals(coordBean.getCreatedTime(), retCoordBean.getCreatedTime());
+    }
 }

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/core/src/test/java/org/apache/oozie/executor/jpa/TestWorkflowsJobGetJPAExecutor.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/oozie/executor/jpa/TestWorkflowsJobGetJPAExecutor.java b/core/src/test/java/org/apache/oozie/executor/jpa/TestWorkflowsJobGetJPAExecutor.java
index 46b0d05..ddb5506 100644
--- a/core/src/test/java/org/apache/oozie/executor/jpa/TestWorkflowsJobGetJPAExecutor.java
+++ b/core/src/test/java/org/apache/oozie/executor/jpa/TestWorkflowsJobGetJPAExecutor.java
@@ -93,6 +93,10 @@ public class TestWorkflowsJobGetJPAExecutor extends XDataTestCase {
         assertNotNull(wfInfo);
         assertEquals(wfInfo.getWorkflows().size(), 1);
         WorkflowJobBean retBean = wfInfo.getWorkflows().get(0);
+        compareWf(wfBean, retBean);
+    }
+
+    private void compareWf(WorkflowJobBean wfBean, WorkflowJobBean retBean) {
         assertEquals(wfBean.getId(), retBean.getId());
         assertEquals(wfBean.getAppName(), retBean.getAppName());
         assertEquals(wfBean.getStatusStr(), retBean.getStatusStr());
@@ -107,6 +111,43 @@ public class TestWorkflowsJobGetJPAExecutor extends XDataTestCase {
         assertEquals(wfBean.getParentId(), retBean.getParentId());
     }
 
+    public void testWfJobsSortBy() throws Exception {
+        WorkflowJobBean workflowJob1 = addRecordToWfJobTable(WorkflowJob.Status.PREP, WorkflowInstance.Status.PREP);
+        WorkflowJobBean workflowJob2 = addRecordToWfJobTable(WorkflowJob.Status.PREP, WorkflowInstance.Status.PREP);
+        workflowJob1.setAppName("update-app-name-1");
+        workflowJob1.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-04T10:00Z"));
+        workflowJob1.setCreatedTime(DateUtils.parseDateUTC("2012-01-03T10:00Z"));
+        WorkflowJobQueryExecutor.getInstance().executeUpdate(WorkflowJobQuery.UPDATE_WORKFLOW, workflowJob1);
+        workflowJob2.setAppName("update-app-name-2");
+        workflowJob2.setLastModifiedTime(DateUtils.parseDateUTC("2012-01-05T10:00Z"));
+        workflowJob2.setCreatedTime(DateUtils.parseDateUTC("2012-01-02T10:00Z"));
+        WorkflowJobQueryExecutor.getInstance().executeUpdate(WorkflowJobQuery.UPDATE_WORKFLOW, workflowJob2);
+
+        JPAService jpaService = Services.get().get(JPAService.class);
+        assertNotNull(jpaService);
+        Map<String, List<String>> filter = new HashMap<String, List<String>>();
+        List<String> list = new ArrayList<String>();
+        list.add("lastModifiedTime");
+        filter.put(OozieClient.FILTER_SORT_BY, list);
+        WorkflowsJobGetJPAExecutor wfGetCmd = new WorkflowsJobGetJPAExecutor(filter, 1, 20);
+        WorkflowsInfo wfInfo = jpaService.execute(wfGetCmd);
+        assertNotNull(wfInfo);
+        assertEquals(2, wfInfo.getWorkflows().size());
+        WorkflowJobBean retBean = wfInfo.getWorkflows().get(0);
+        compareWf(workflowJob2, retBean);
+        // test default behavior
+        filter.clear();
+        list.clear();
+        list.add("dummyField");
+        filter.put(OozieClient.FILTER_SORT_BY, list);
+        wfGetCmd = new WorkflowsJobGetJPAExecutor(filter, 1, 20);
+        wfInfo = jpaService.execute(wfGetCmd);
+        assertNotNull(wfInfo);
+        assertEquals(2, wfInfo.getWorkflows().size());
+        retBean = wfInfo.getWorkflows().get(0);
+        compareWf(workflowJob1, retBean);
+    }
+
     public void testWfJobsGetWithCreatedTime() throws Exception {
         JPAService jpaService = Services.get().get(JPAService.class);
         Date createdTime1 = DateUtils.parseDateUTC("2012-01-01T10:00Z");

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/docs/src/site/twiki/DG_CommandLineTool.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/DG_CommandLineTool.twiki b/docs/src/site/twiki/DG_CommandLineTool.twiki
index f72bad8..af29b56 100644
--- a/docs/src/site/twiki/DG_CommandLineTool.twiki
+++ b/docs/src/site/twiki/DG_CommandLineTool.twiki
@@ -100,7 +100,8 @@ usage:
       oozie jobs <OPTIONS> : jobs status
                  -auth <arg>          select authentication type [SIMPLE|KERBEROS]
                  -doas <arg>          doAs user, impersonates as the specified user.
-                 -filter <arg>        user=<U>\;name=<N>\;group=<G>\;status=<S>\;frequency=<F>\;unit=<M>\;startcreatedtime=<SC>\;endcreatedtime=<EC>
+                 -filter <arg>        user=<U>\;name=<N>\;group=<G>\;status=<S>\;frequency=<F>\;unit=<M>\;startcreatedtime=<SC>\;
+                                      endcreatedtime=<EC>\;sortby=<SB>
                  -jobtype <arg>       job type ('Supported in Oozie-2.0 or later versions ONLY - coordinator' or 'wf' (default))
                  -len <arg>           number of jobs (default '100')
                  -localtime           use local time (same as passing your time zone to -timezone). Overrides -timezone option
@@ -962,6 +963,7 @@ Valid filter names are:
    * status: the status of the job.
    * startcreatedtime: the start of time window in specifying createdtime range filter.
    * endcreatedtime: the end of time window in specifying createdtime range filter
+   * sortby: order the results. Supported values for =sortby= are: =createdTime= and =lastModifiedTime=
 
 The query will do an AND among all the filter names. The query will do an OR among all the filter values for the same
 name. Multiple values must be specified as different name value pairs.
@@ -995,6 +997,7 @@ Valid filter names are:
    * status: the status of the job.
    * frequency: the frequency of the Coordinator job.
    * unit: the time unit. It can take one of the following four values: months, days, hours or minutes. Time unit should be added only when frequency is specified.
+   * sortby: order the results. Supported values for =sortby= are: =createdTime= and =lastModifiedTime=
 
 ---+++ Checking the Status of multiple Bundle Jobs
 
@@ -1055,6 +1058,7 @@ Valid filter names are:
    * status: the status of the job.
    * frequency: the frequency of the Coordinator job.
    * unit: the time unit. It can take one of the following four values: months, days, hours or minutes. Time unit should be added only when frequency is specified.
+   * sortby: order the results. Supported values for =sortby= are: =createdTime= and =lastModifiedTime=
 
 The query will do an AND among all the filter names. The query will do an OR among all the filter values for the same
 name. Multiple values must be specified as different name value pairs.

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/docs/src/site/twiki/WebServicesAPI.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/WebServicesAPI.twiki b/docs/src/site/twiki/WebServicesAPI.twiki
index a34f2d3..5dadafe 100644
--- a/docs/src/site/twiki/WebServicesAPI.twiki
+++ b/docs/src/site/twiki/WebServicesAPI.twiki
@@ -1663,6 +1663,7 @@ Valid filter names are:
    * status: the status of the job
    * startCreatedTime : the start of the window about workflow job's created time
    * endCreatedTime : the end of above window
+   * sortby: order the results. Supported values for =sortby= are: =createdTime= and =lastModifiedTime=
 
 The query will do an AND among all the filter names.
 

http://git-wip-us.apache.org/repos/asf/oozie/blob/9650a728/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index e37008f..617c814 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -1,5 +1,6 @@
 -- Oozie 4.3.0 release (trunk - unreleased)
 
+OOZIE-2520 SortBy filter for ordering the jobs query results (abhishekbafna via jaydeepvishwakarma)
 OOZIE-2506 Add logs into RecoverService for logging information about queued commands (abhishekbafna via jaydeepvishwakarma) 
 OOZIE-2515 Duplicate information for "Changing endtime/pausetime of a Bundle Job" in CommandLineTool wiki (abhishekbafna via jaydeepvishwakarma)
 OOZIE-2390 Rerun with failed option removing completed output data (jaydeepvishwakarma)