ATLAS-4422 : Quick Search: Provide sorting

Signed-off-by: Pinal Shah <pinal.shah@freestoneinfotech.com>
diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java b/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
index 9e5e977..79f5aae 100644
--- a/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
+++ b/intg/src/main/java/org/apache/atlas/model/discovery/QuickSearchParameters.java
@@ -22,6 +22,7 @@
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 
+import org.apache.atlas.SortOrder;
 import org.apache.atlas.model.discovery.SearchParameters.FilterCriteria;
 
 import java.io.Serializable;
@@ -47,6 +48,8 @@
     private int            offset;
     private int            limit;
     private Set<String>    attributes;
+    private String         sortBy;
+    private SortOrder      sortOrder;
 
     /**
      * for framework use.
@@ -61,7 +64,9 @@
                                  boolean        excludeDeletedEntities,
                                  int            offset,
                                  int            limit,
-                                 Set<String>    attributes) {
+                                 Set<String>    attributes,
+                                 String         sortBy,
+                                 SortOrder      sortOrder) {
         this.query                  = query;
         this.typeName               = typeName;
         this.entityFilters          = entityFilters;
@@ -70,6 +75,8 @@
         this.offset                 = offset;
         this.limit                  = limit;
         this.attributes             = attributes;
+        this.sortBy                 = sortBy;
+        this.sortOrder              = sortOrder;
     }
 
     public String getQuery() {
@@ -135,4 +142,20 @@
     public void setAttributes(Set<String> attributes) {
         this.attributes = attributes;
     }
+
+    public String getSortBy() {
+        return sortBy;
+    }
+
+    public void setSortBy(String sortBy) {
+        this.sortBy = sortBy;
+    }
+
+    public SortOrder getSortOrder() {
+        return sortOrder;
+    }
+
+    public void setSortOrder(SortOrder sortOrder) {
+        this.sortOrder = sortOrder;
+    }
 }
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 5b3b948..8fbc22f 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -920,6 +920,8 @@
         searchParameters.setOffset(quickSearchParameters.getOffset());
         searchParameters.setEntityFilters(quickSearchParameters.getEntityFilters());
         searchParameters.setAttributes(quickSearchParameters.getAttributes());
+        searchParameters.setSortBy(quickSearchParameters.getSortBy());
+        searchParameters.setSortOrder(quickSearchParameters.getSortOrder());
 
         return searchParameters;
     }
diff --git a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
index 5e47295..8c257d8 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
@@ -859,6 +859,44 @@
     }
 
     @Test
+    public void searchWithEntityQuickSearchSortAsc() throws AtlasBaseException {
+        QuickSearchParameters params = new QuickSearchParameters();
+        params.setTypeName("hive_table");
+        params.setQuery("sales");
+        params.setExcludeDeletedEntities(true);
+        params.setLimit(3);
+        params.setSortBy("owner");
+        params.setSortOrder(SortOrder.ASCENDING);
+
+        AtlasQuickSearchResult searchResult = discoveryService.quickSearch(params);
+        List<AtlasEntityHeader> list = searchResult.getSearchResults().getEntities();
+
+        Assert.assertTrue(CollectionUtils.isNotEmpty(list));
+        Assert.assertTrue(list.size() == 3);
+        Assert.assertTrue(list.get(0).getAttribute("owner").toString().equalsIgnoreCase("Jane BI"));
+        Assert.assertTrue(list.get(1).getAttribute("owner").toString().equalsIgnoreCase("Joe"));
+    }
+
+    @Test
+    public void searchWithEntityQuickSearchSortDesc() throws AtlasBaseException {
+        QuickSearchParameters params = new QuickSearchParameters();
+        params.setTypeName("hive_table");
+        params.setQuery("sales");
+        params.setExcludeDeletedEntities(true);
+        params.setLimit(3);
+        params.setSortBy("name");
+        params.setSortOrder(SortOrder.DESCENDING);
+
+        AtlasQuickSearchResult searchResult = discoveryService.quickSearch(params);
+        List<AtlasEntityHeader> list = searchResult.getSearchResults().getEntities();
+
+        Assert.assertTrue(CollectionUtils.isNotEmpty(list));
+        Assert.assertTrue(list.size() == 3);
+        Assert.assertTrue(list.get(0).getDisplayText().equalsIgnoreCase("time_dim"));
+        Assert.assertTrue(list.get(1).getDisplayText().equalsIgnoreCase("sales_fact_monthly_mv"));
+    }
+
+    @Test
     public void searchRelatedEntitiesSortAsc() throws AtlasBaseException {
         String guid = gethiveTableSalesFactGuid();
 
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
index e4c74a9..287b611 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
@@ -606,11 +606,13 @@
     @Path("/quick")
     @GET
     @Timed
-    public AtlasQuickSearchResult quickSearch(@QueryParam("query")                  String  query,
-                                              @QueryParam("typeName")               String  typeName,
-                                              @QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities,
-                                              @QueryParam("offset")                 int     offset,
-                                              @QueryParam("limit")                  int     limit) throws AtlasBaseException {
+    public AtlasQuickSearchResult quickSearch(@QueryParam("query")                  String    query,
+                                              @QueryParam("typeName")               String    typeName,
+                                              @QueryParam("excludeDeletedEntities") boolean   excludeDeletedEntities,
+                                              @QueryParam("offset")                 int       offset,
+                                              @QueryParam("limit")                  int       limit,
+                                              @QueryParam("sortBy")                 String    sortByAttribute,
+                                              @QueryParam("sortOrder")              SortOrder sortOrder) throws AtlasBaseException {
 
 
 
@@ -633,7 +635,9 @@
                                                                                     excludeDeletedEntities,
                                                                                     offset,
                                                                                     limit,
-                                                                                    null); // attributes
+                                                                                    null, // attributes
+                                                                                    sortByAttribute,
+                                                                                    sortOrder);
 
             return discoveryService.quickSearch(quickSearchParameters);
         } finally {
@@ -673,6 +677,11 @@
                 throw new AtlasBaseException(AtlasErrorCode.INVALID_SEARCH_PARAMS);
             }
 
+            if (StringUtils.isEmpty(quickSearchParameters.getTypeName()) &&
+                    (StringUtils.isNotEmpty(quickSearchParameters.getSortBy()))) {
+                throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "SortBy specified without Type name");
+            }
+
             validateSearchParameters(quickSearchParameters);
 
             return discoveryService.quickSearch(quickSearchParameters);