You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by ra...@apache.org on 2015/10/09 06:17:06 UTC

[01/50] [abbrv] lens git commit: LENS-754 : Remove DISCLAIMER file from install and run docs

Repository: lens
Updated Branches:
  refs/heads/current-release-line 1237842ab -> 867142113


LENS-754 : Remove DISCLAIMER file from install and run docs


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

Branch: refs/heads/current-release-line
Commit: e9d5eaadba166bafd7fd0d3adee80ced810309b0
Parents: 4061227
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Tue Aug 25 13:55:56 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Tue Aug 25 15:06:05 2015 +0530

----------------------------------------------------------------------
 src/site/apt/lenshome/install-and-run.apt | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/e9d5eaad/src/site/apt/lenshome/install-and-run.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/lenshome/install-and-run.apt b/src/site/apt/lenshome/install-and-run.apt
index 0c55c5a..491bbee 100644
--- a/src/site/apt/lenshome/install-and-run.apt
+++ b/src/site/apt/lenshome/install-and-run.apt
@@ -46,7 +46,6 @@ Installing and Running Lens
   ├── LICENSE
   ├── NOTICE
   ├── README
-  ├── DISCLAIMER
   ├── LICENSE*
   └── server
 +---+


[44/50] [abbrv] lens git commit: Merge remote-tracking branch 'origin/master'

Posted by ra...@apache.org.
Merge remote-tracking branch 'origin/master'


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/02760a3a
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/02760a3a
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/02760a3a

Branch: refs/heads/current-release-line
Commit: 02760a3aa4249fa00a3456048c379a6ba32b930c
Parents: d7f09ed 2ecef11
Author: Raju Bairishetti <ra...@im0933-x0.corp.inmobi.com>
Authored: Thu Oct 8 15:04:16 2015 +0530
Committer: Raju Bairishetti <ra...@im0933-x0.corp.inmobi.com>
Committed: Thu Oct 8 15:04:16 2015 +0530

----------------------------------------------------------------------
 .../lens/server/api/query/QueryContext.java     |  3 +
 .../metastore/CubeMetastoreServiceImpl.java     | 60 ++++++++++----------
 .../server/query/QueryExecutionServiceImpl.java |  4 +-
 lens-ui/pom.xml                                 | 36 ++----------
 pom.xml                                         | 21 ++++++-
 src/site/apt/developer/contribute.apt           |  8 ++-
 6 files changed, 64 insertions(+), 68 deletions(-)
----------------------------------------------------------------------



[21/50] [abbrv] lens git commit: LENS-392 : Look ahead timerange should not look for all finer granularity partitions to be present

Posted by ra...@apache.org.
LENS-392 : Look ahead timerange should not look for all finer granularity partitions to be present


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/08135aa6
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/08135aa6
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/08135aa6

Branch: refs/heads/current-release-line
Commit: 08135aa693658aa454e55a2c1e81c9e0fa19444b
Parents: 4e81ef4
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Wed Sep 16 09:50:55 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Wed Sep 16 09:50:55 2015 +0530

----------------------------------------------------------------------
 .../lens/cube/metadata/FactPartition.java       | 14 ++-
 .../lens/cube/metadata/TimePartition.java       |  9 ++
 .../lens/cube/metadata/TimePartitionRange.java  |  5 +
 .../timeline/RangesPartitionTimeline.java       |  4 +-
 .../cube/parse/AbridgedTimeRangeWriter.java     |  5 +-
 .../lens/cube/parse/StorageTableResolver.java   | 43 ++++-----
 .../apache/lens/cube/parse/CubeTestSetup.java   | 52 ++++++-----
 .../lens/cube/parse/TestCubeRewriter.java       | 97 ++++++++++----------
 8 files changed, 130 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/metadata/FactPartition.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/FactPartition.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/FactPartition.java
index fc2d85b..f934ad3 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/FactPartition.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/FactPartition.java
@@ -42,6 +42,7 @@ public class FactPartition implements Comparable<FactPartition> {
   @Getter
   @Setter
   private FactPartition containingPart;
+  @Getter
   private final DateFormat partFormat;
   @Getter
   @Setter
@@ -59,7 +60,18 @@ public class FactPartition implements Comparable<FactPartition> {
   public FactPartition(String partCol, Date partSpec, UpdatePeriod period, FactPartition containingPart,
     DateFormat partFormat, Set<String> storageTables) {
     this(partCol, partSpec, period, containingPart, partFormat);
-    this.storageTables.addAll(storageTables);
+    if (storageTables != null) {
+      this.storageTables.addAll(storageTables);
+    }
+  }
+
+  public FactPartition(String partCol, TimePartition timePartition) {
+    this(partCol, timePartition, null, null);
+  }
+
+  public FactPartition(String partCol, TimePartition timePartition, FactPartition containingPart, Set<String>
+    storageTables) {
+    this(partCol, timePartition.getDate(), timePartition.getUpdatePeriod(), containingPart, null, storageTables);
   }
 
   public boolean hasContainingPart() {

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
index d52f168..0026262 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
@@ -121,6 +121,7 @@ public class TimePartition implements Comparable<TimePartition>, Named {
     return rangeUpto(next());
   }
 
+
   @Override
   public String getName() {
     return getDateString();
@@ -129,4 +130,12 @@ public class TimePartition implements Comparable<TimePartition>, Named {
   public TimePartitionRange emptyRange() throws LensException {
     return this.rangeUpto(this);
   }
+
+  public static TimePartition max(TimePartition p1, TimePartition p2) {
+    return p1.compareTo(p2) >= 0 ? p1 : p2;
+  }
+
+  public static TimePartition min(TimePartition p1, TimePartition p2) {
+    return p1.compareTo(p2) < 0 ? p1 : p2;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
index f5f8d4c..01069a5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.cube.metadata;
 
+import java.util.Date;
 import java.util.Iterator;
 
 import org.apache.lens.cube.parse.DateUtil;
@@ -33,6 +34,10 @@ public class TimePartitionRange implements Iterable<TimePartition>, Named {
   private TimePartition begin;
   private TimePartition end;
 
+  public static TimePartitionRange between(Date from, Date to, UpdatePeriod period) throws LensException {
+    return TimePartition.of(period, from).rangeUpto(TimePartition.of(period, to));
+  }
+
   public TimePartitionRange(TimePartition begin, TimePartition end) throws LensException {
     if (end.before(begin)) {
       throw new LensException("condition of creation of timepartition failed: end>=begin");

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/RangesPartitionTimeline.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/RangesPartitionTimeline.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/RangesPartitionTimeline.java
index 1b9a44a..6c9eb7a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/RangesPartitionTimeline.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/RangesPartitionTimeline.java
@@ -132,9 +132,9 @@ public class RangesPartitionTimeline extends PartitionTimeline {
 
   private void mergeRanges() {
     for (int i = 0; i < ranges.size() - 1; i++) {
-      if (ranges.get(i).getEnd().equals(ranges.get(i + 1).getBegin())) {
+      if (ranges.get(i).getEnd().compareTo(ranges.get(i + 1).getBegin()) >= 0) {
         TimePartitionRange removed = ranges.remove(i + 1);
-        ranges.get(i).setEnd(removed.getEnd());
+        ranges.get(i).setEnd(TimePartition.max(removed.getEnd(), ranges.get(i).getEnd()));
         i--; // check again at same index
       } else if (ranges.get(i).isEmpty()) {
         ranges.remove(i);

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/parse/AbridgedTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AbridgedTimeRangeWriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AbridgedTimeRangeWriter.java
index 2caea56..8681e90 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AbridgedTimeRangeWriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AbridgedTimeRangeWriter.java
@@ -121,11 +121,12 @@ public class AbridgedTimeRangeWriter implements TimeRangeWriter {
     Map<FactPartition, Set<FactPartition>> partitionSetMap = new HashMap<FactPartition, Set<FactPartition>>();
     for (FactPartition part : parts) {
       FactPartition key = part.getContainingPart();
-      part.setContainingPart(null);
+      FactPartition part2 = new FactPartition(part.getPartCol(), part.getPartSpec(), part.getPeriod(), null, part
+        .getPartFormat(), part.getStorageTables());
       if (partitionSetMap.get(key) == null) {
         partitionSetMap.put(key, Sets.<FactPartition>newTreeSet());
       }
-      partitionSetMap.get(key).add(part);
+      partitionSetMap.get(key).add(part2);
     }
     Map<Set<FactPartition>, Set<FactPartition>> setSetOppositeMap = Maps.newHashMap();
     for (Map.Entry<FactPartition, Set<FactPartition>> entry : partitionSetMap.entrySet()) {

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
index 58d0fa7..68ab5ab 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
@@ -369,7 +369,7 @@ class StorageTableResolver implements ContextRewriter {
         // If no partitions were found, then we'll fallback.
         String partCol = range.getPartitionColumn();
         boolean partColNotSupported = rangeParts.isEmpty();
-        for(String storage: cfact.fact.getStorages()) {
+        for (String storage : cfact.fact.getStorages()) {
           String storageTableName = getFactOrDimtableStorageTableName(cfact.fact.getName(), storage).toLowerCase();
           partColNotSupported &= skipStorageCauses.containsKey(storageTableName)
             && skipStorageCauses.get(storageTableName).getCause().equals(PART_COL_DOES_NOT_EXIST)
@@ -484,11 +484,11 @@ class StorageTableResolver implements ContextRewriter {
           minimalPartsCopy.retainAll(rangeParts);
           if (!StringUtils.isEmpty(whereClauseForFallback.get(trange))) {
             rangeToWhere.put(
-                rangeWriter.getTimeRangeWhereClause(cubeql, cubeql.getAliasForTableName(cubeql.getCube().getName()),
-                    minimalPartsCopy) + " and  " + whereClauseForFallback.get(trange), table);
+              rangeWriter.getTimeRangeWhereClause(cubeql, cubeql.getAliasForTableName(cubeql.getCube().getName()),
+                minimalPartsCopy) + " and  " + whereClauseForFallback.get(trange), table);
           } else {
             rangeToWhere.put(rangeWriter.getTimeRangeWhereClause(cubeql,
-                cubeql.getAliasForTableName(cubeql.getCube().getName()), minimalPartsCopy), table);
+              cubeql.getAliasForTableName(cubeql.getCube().getName()), minimalPartsCopy), table);
           }
         }
         cfact.getRangeToStorageWhereMap().put(trange, rangeToWhere);
@@ -506,7 +506,7 @@ class StorageTableResolver implements ContextRewriter {
     HashMap<String, SkipStorageCause> skipStorageCauses,
     PartitionRangesForPartitionColumns missingPartitions) throws LensException {
     try {
-      return getPartitions(fact, range, getValidUpdatePeriods(fact), true, skipStorageCauses,
+      return getPartitions(fact, range, getValidUpdatePeriods(fact), true, failOnPartialData, skipStorageCauses,
         missingPartitions);
     } catch (Exception e) {
       throw new LensException(e);
@@ -514,22 +514,22 @@ class StorageTableResolver implements ContextRewriter {
   }
 
   private Set<FactPartition> getPartitions(CubeFactTable fact, TimeRange range, TreeSet<UpdatePeriod> updatePeriods,
-    boolean addNonExistingParts, Map<String, SkipStorageCause> skipStorageCauses,
+    boolean addNonExistingParts, boolean failOnPartialData, Map<String, SkipStorageCause> skipStorageCauses,
     PartitionRangesForPartitionColumns missingPartitions)
     throws Exception {
-    Set<FactPartition> partitions = new TreeSet<FactPartition>();
+    Set<FactPartition> partitions = new TreeSet<>();
     if (range != null && range.isCoverableBy(updatePeriods)
       && getPartitions(fact, range.getFromDate(), range.getToDate(), range.getPartitionColumn(), partitions,
-        updatePeriods, addNonExistingParts, skipStorageCauses, missingPartitions)) {
+        updatePeriods, addNonExistingParts, failOnPartialData, skipStorageCauses, missingPartitions)) {
       return partitions;
     } else {
-      return new TreeSet<FactPartition>();
+      return new TreeSet<>();
     }
   }
 
   private boolean getPartitions(CubeFactTable fact, Date fromDate, Date toDate, String partCol,
     Set<FactPartition> partitions, TreeSet<UpdatePeriod> updatePeriods,
-    boolean addNonExistingParts, Map<String, SkipStorageCause> skipStorageCauses,
+    boolean addNonExistingParts, boolean failOnPartialData, Map<String, SkipStorageCause> skipStorageCauses,
     PartitionRangesForPartitionColumns missingPartitions)
     throws Exception {
     log.info("getPartitions for {} from fromDate:{} toDate:{}", fact, fromDate, toDate);
@@ -629,21 +629,18 @@ class StorageTableResolver implements ContextRewriter {
                 log.debug("Looking for process time partitions between {} and {}", pdt, nextPdt);
                 Set<FactPartition> processTimeParts =
                   getPartitions(fact, TimeRange.getBuilder().fromDate(pdt).toDate(nextPdt).partitionColumn(
-                    processTimePartCol).build(), newset, false, skipStorageCauses, missingPartitions);
+                    processTimePartCol).build(), newset, true, false, skipStorageCauses, missingPartitions);
                 log.debug("Look ahead partitions: {}", processTimeParts);
                 TimeRange timeRange = TimeRange.getBuilder().fromDate(dt).toDate(nextDt).build();
                 for (FactPartition pPart : processTimeParts) {
                   log.debug("Looking for finer partitions in pPart: {}", pPart);
                   for (Date date : timeRange.iterable(pPart.getPeriod(), 1)) {
-                    partitions.add(new FactPartition(partCol, date, pPart.getPeriod(), pPart,
-                      partWhereClauseFormat));
+                    FactPartition innerPart = new FactPartition(partCol, date, pPart.getPeriod(), pPart,
+                      partWhereClauseFormat);
+                    updateFactPartitionStorageTablesFrom(fact, innerPart, pPart.getStorageTables());
+                    partitions.add(innerPart);
                   }
                   log.debug("added all sub partitions blindly in pPart: {}", pPart);
-                  //                          if (!getPartitions(fact, dt, cal.getTime(), partCol, pPart, partitions,
-                  // newset, false,
-                  //                            skipStorageCauses, nonExistingParts)) {
-                  //                            log.info("No partitions found in look ahead range");
-                  //                          }
                 }
               }
             }
@@ -654,7 +651,7 @@ class StorageTableResolver implements ContextRewriter {
         TreeSet<UpdatePeriod> newset = new TreeSet<UpdatePeriod>();
         newset.addAll(updatePeriods);
         newset.remove(interval);
-        if (!getPartitions(fact, dt, nextDt, partCol, partitions, newset, false, skipStorageCauses,
+        if (!getPartitions(fact, dt, nextDt, partCol, partitions, newset, false, failOnPartialData, skipStorageCauses,
           missingPartitions)) {
 
           log.debug("Adding non existing partition {}", part);
@@ -676,13 +673,13 @@ class StorageTableResolver implements ContextRewriter {
       }
     }
     return getPartitions(fact, fromDate, ceilFromDate, partCol, partitions,
-      updatePeriods, addNonExistingParts, skipStorageCauses, missingPartitions)
+      updatePeriods, addNonExistingParts, failOnPartialData, skipStorageCauses, missingPartitions)
       && getPartitions(fact, floorToDate, toDate, partCol, partitions,
-        updatePeriods, addNonExistingParts, skipStorageCauses, missingPartitions);
+        updatePeriods, addNonExistingParts, failOnPartialData, skipStorageCauses, missingPartitions);
   }
 
-  private void updateFactPartitionStorageTablesFrom(CubeFactTable fact, FactPartition part,
-    Set<String> storageTableNames) throws LensException, HiveException, ParseException {
+  void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
+    FactPartition part, Set<String> storageTableNames) throws LensException, HiveException, ParseException {
     for (String storageTableName : storageTableNames) {
       if (client.factPartitionExists(fact, part, storageTableName)) {
         part.getStorageTables().add(storageTableName);

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
index 7f56292..67f7ab9 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
@@ -19,6 +19,10 @@
 
 package org.apache.lens.cube.parse;
 
+import static java.util.Calendar.DAY_OF_MONTH;
+import static java.util.Calendar.HOUR_OF_DAY;
+import static java.util.Calendar.MONTH;
+
 import static org.apache.lens.cube.metadata.UpdatePeriod.*;
 
 import static org.testng.Assert.assertEquals;
@@ -142,31 +146,31 @@ public class CubeTestSetup {
     log.debug("Test now:{}", NOW);
 
     // Figure out if current hour is 0th hour
-    zerothHour = (cal.get(Calendar.HOUR_OF_DAY) == 0);
+    zerothHour = (cal.get(HOUR_OF_DAY) == 0);
 
     // Figure out last hour
-    cal.add(Calendar.HOUR_OF_DAY, -1);
+    cal.add(HOUR_OF_DAY, -1);
     LAST_HOUR = cal.getTime();
     log.debug("LastHour:{}", LAST_HOUR);
 
     cal.setTime(NOW);
-    cal.add(Calendar.DAY_OF_MONTH, -1);
+    cal.add(DAY_OF_MONTH, -1);
     ONE_DAY_BACK = cal.getTime();
-    cal.add(Calendar.DAY_OF_MONTH, -1);
+    cal.add(DAY_OF_MONTH, -1);
     TWODAYS_BACK = cal.getTime();
     System.out.println("Test TWODAYS_BACK:" + TWODAYS_BACK);
 
     // two months back
     cal.setTime(NOW);
-    cal.add(Calendar.MONTH, -2);
+    cal.add(MONTH, -2);
     TWO_MONTHS_BACK = cal.getTime();
     System.out.println("Test TWO_MONTHS_BACK:" + TWO_MONTHS_BACK);
 
     // Before 4days
     cal.setTime(NOW);
-    cal.add(Calendar.DAY_OF_MONTH, -4);
+    cal.add(DAY_OF_MONTH, -4);
     BEFORE_4_DAYS_END = cal.getTime();
-    cal.add(Calendar.DAY_OF_MONTH, -2);
+    cal.add(DAY_OF_MONTH, -2);
     BEFORE_4_DAYS_START = cal.getTime();
 
 
@@ -426,7 +430,7 @@ public class CubeTestSetup {
     }
     Calendar cal = new GregorianCalendar();
     cal.setTime(dayStart);
-    if (cal.get(Calendar.DAY_OF_MONTH) != 1) {
+    if (cal.get(DAY_OF_MONTH) != 1) {
       addParts(dailyparts, DAILY, dayStart, DateUtil.getCeilDate(TWO_MONTHS_BACK, MONTHLY));
       monthStart = DateUtil.getCeilDate(TWO_MONTHS_BACK, MONTHLY);
     }
@@ -478,7 +482,7 @@ public class CubeTestSetup {
     }
     Calendar cal = new GregorianCalendar();
     cal.setTime(dayStart);
-    if (cal.get(Calendar.DAY_OF_MONTH) != 1) {
+    if (cal.get(DAY_OF_MONTH) != 1) {
       addParts(dailyparts, DAILY, dayStart, DateUtil.getCeilDate(TWO_MONTHS_BACK, MONTHLY));
       monthStart = DateUtil.getCeilDate(TWO_MONTHS_BACK, MONTHLY);
     }
@@ -1277,7 +1281,7 @@ public class CubeTestSetup {
       timeParts.put("ttd2", temp);
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, HOURLY);
       client.addPartition(sPartSpec, c99);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
 
@@ -1290,7 +1294,7 @@ public class CubeTestSetup {
       timeParts.put("ttd2", temp);
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, HOURLY);
       client.addPartition(sPartSpec, c99);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
   }
@@ -1392,7 +1396,7 @@ public class CubeTestSetup {
       } catch (LensException e) {
         log.error("Encountered Lens exception.", e);
       }
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
 
@@ -1404,7 +1408,7 @@ public class CubeTestSetup {
       timeParts.put(TestCubeMetastoreClient.getDatePartitionKey(), temp);
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, HOURLY);
       client.addPartition(sPartSpec, c1);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
     client.clearHiveTableCache();
@@ -1438,7 +1442,7 @@ public class CubeTestSetup {
       partitions.add(HOURLY.format().format(temp));
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, HOURLY);
       storagePartitionDescs.add(sPartSpec);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
     client.addPartitions(storagePartitionDescs, c4);
@@ -1457,7 +1461,7 @@ public class CubeTestSetup {
       timeParts.put("ttd2", temp);
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, HOURLY);
       client.addPartition(sPartSpec, c4);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
   }
@@ -1516,7 +1520,7 @@ public class CubeTestSetup {
       timeParts.put(TestCubeMetastoreClient.getDatePartitionKey(), temp);
       StoragePartitionDesc sPartSpec = new StoragePartitionDesc(fact2.getName(), timeParts, null, HOURLY);
       client.addPartition(sPartSpec, c3);
-      cal.add(Calendar.HOUR_OF_DAY, 1);
+      cal.add(HOUR_OF_DAY, 1);
       temp = cal.getTime();
     }
   }
@@ -2309,10 +2313,10 @@ public class CubeTestSetup {
     // Add partitions in PIE storage
     Calendar pcal = Calendar.getInstance();
     pcal.setTime(TWODAYS_BACK);
-    pcal.set(Calendar.HOUR, 0);
+    pcal.set(HOUR_OF_DAY, 0);
     Calendar ical = Calendar.getInstance();
     ical.setTime(TWODAYS_BACK);
-    ical.set(Calendar.HOUR, 0);
+    ical.set(HOUR_OF_DAY, 0);
 
     Map<UpdatePeriod, TreeSet<Date>> pTimes = Maps.newHashMap();
     pTimes.put(DAILY, Sets.<Date>newTreeSet());
@@ -2343,8 +2347,8 @@ public class CubeTestSetup {
         pTimes.get(DAILY).add(ptime);
         iTimes.get(DAILY).add(itime);
         client.addPartition(sPartSpec, storageName);
-        pcal.add(Calendar.DAY_OF_MONTH, 1);
-        ical.add(Calendar.HOUR_OF_DAY, 20);
+        pcal.add(DAY_OF_MONTH, 1);
+        ical.add(HOUR_OF_DAY, 20);
       } else if (p == 2) { // day2
         // pt=day2-hour[0-3] it = day1-hour[20-23]
         // pt=day2 and it=day1
@@ -2372,8 +2376,8 @@ public class CubeTestSetup {
           pTimes.get(HOURLY).add(ptime);
           iTimes.get(HOURLY).add(itime);
           client.addPartition(sPartSpec, storageName);
-          pcal.add(Calendar.HOUR_OF_DAY, 1);
-          ical.add(Calendar.HOUR_OF_DAY, 1);
+          pcal.add(HOUR_OF_DAY, 1);
+          ical.add(HOUR_OF_DAY, 1);
         }
         // pt=day2 and it=day2
         sPartSpec = new StoragePartitionDesc(fact.getName(), timeParts, null, DAILY);
@@ -2394,8 +2398,8 @@ public class CubeTestSetup {
           pTimes.get(HOURLY).add(ptime);
           iTimes.get(HOURLY).add(itime);
           client.addPartition(sPartSpec, storageName);
-          pcal.add(Calendar.HOUR_OF_DAY, 1);
-          ical.add(Calendar.HOUR_OF_DAY, 1);
+          pcal.add(HOUR_OF_DAY, 1);
+          ical.add(HOUR_OF_DAY, 1);
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/08135aa6/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
index 7e5184c..a58f5fe 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
@@ -19,6 +19,8 @@
 
 package org.apache.lens.cube.parse;
 
+import static org.apache.lens.cube.metadata.UpdatePeriod.DAILY;
+import static org.apache.lens.cube.metadata.UpdatePeriod.HOURLY;
 import static org.apache.lens.cube.parse.CandidateTablePruneCause.CandidateTablePruneCode.*;
 import static org.apache.lens.cube.parse.CubeTestSetup.*;
 
@@ -46,6 +48,8 @@ import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
@@ -91,14 +95,14 @@ public class TestCubeRewriter extends TestQueryRewrite {
     String qFrom = qFmt.format(from2DaysBackDate);
 
     CubeQueryContext rewrittenQuery = rewriteCtx("select SUM(msr15) from testCube where"
-      + " time_range_in(d_time, '"+ qFrom + "', '" + qTo + "')", conf);
+      + " time_range_in(d_time, '" + qFrom + "', '" + qTo + "')", conf);
 
     DateFormat fmt = UpdatePeriod.CONTINUOUS.format();
     String to = fmt.format(toDate);
     String from = fmt.format(from2DaysBackDate);
 
     String expected = "select SUM((testCube.msr15)) from TestQueryRewrite.c0_testFact_CONTINUOUS testcube"
-        + " WHERE ((( testcube . dt ) between  '" + from + "'  and  '" + to + "' ))";
+      + " WHERE ((( testcube . dt ) between  '" + from + "'  and  '" + to + "' ))";
     System.out.println("rewrittenQuery.toHQL() " + rewrittenQuery.toHQL());
     System.out.println("expected " + expected);
     compareQueries(expected, rewrittenQuery.toHQL());
@@ -107,7 +111,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
     rewrittenQuery = rewriteCtx("select SUM(msr2) from testCube where" + " time_range_in(d_time, '"
       + qFrom + "', '" + qTo + "')", conf);
     expected = "select SUM((testCube.msr2)) from TestQueryRewrite.c0_testFact testcube"
-        + " WHERE ((( testcube . dt ) between  '" + from + "'  and  '" + to + "' ))";
+      + " WHERE ((( testcube . dt ) between  '" + from + "'  and  '" + to + "' ))";
     System.out.println("rewrittenQuery.toHQL() " + rewrittenQuery.toHQL());
     System.out.println("expected " + expected);
     compareQueries(expected, rewrittenQuery.toHQL());
@@ -117,7 +121,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
     Date from4DaysBackDate = qCal.getTime();
     String qFrom4DaysBackDate = qFmt.format(from4DaysBackDate);
     LensException th = getLensExceptionInRewrite("select SUM(msr15) from testCube where"
-      + " time_range_in(d_time, '"+ qFrom4DaysBackDate + "', '" + qTo + "')", getConf());
+      + " time_range_in(d_time, '" + qFrom4DaysBackDate + "', '" + qTo + "')", getConf());
     assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 
@@ -427,9 +431,9 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("HQL: " + hqlQuery);
 
       String expected1 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c1_testfact"));
+        getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c1_testfact"));
       String expected2 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c2_testfact"));
+        getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c2_testfact"));
 
       System.out.println("Expected1 : " + expected1);
       System.out.println("Expected2 : " + expected2);
@@ -460,9 +464,9 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("HQL:" + hqlQuery);
 
       String expected1 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForDailyAndHourly2days(cubeName, "c1_testfact"));
+        getWhereForDailyAndHourly2days(cubeName, "c1_testfact"));
       String expected2 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForDailyAndHourly2days(cubeName, "c2_testfact"));
+        getWhereForDailyAndHourly2days(cubeName, "c2_testfact"));
 
       System.out.println("Expected1 : " + expected1);
       System.out.println("Expected2 : " + expected2);
@@ -496,11 +500,11 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("HQL:" + hqlQuery);
 
       String expected1 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c1_testfact"));
+        getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c1_testfact"));
       String expected2 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c2_testfact"));
+        getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c2_testfact"));
       String expected3 = getExpectedQuery(cubeName, "select sum(testcube.msr2) FROM ", null, null,
-          getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c3_testfact"));
+        getWhereForMonthlyDailyAndHourly2monthsUnionQuery("c3_testfact"));
 
       System.out.println("Expected1 : " + expected1);
       System.out.println("Expected2 : " + expected2);
@@ -1325,7 +1329,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
   }
 
   @Test
-  public void testFactsWithTimedDimensionWithProcessTimeCol() throws Exception {
+  public void testLookAhead() throws Exception {
     String twoDaysITRange =
       "time_range_in(it, '" + CubeTestSetup.getDateUptoHours(TWODAYS_BACK) + "','"
         + CubeTestSetup.getDateUptoHours(NOW) + "')";
@@ -1333,41 +1337,40 @@ public class TestCubeRewriter extends TestQueryRewrite {
     Configuration conf = getConf();
     conf.set(CubeQueryConfUtil.PROCESS_TIME_PART_COL, "pt");
     conf.setClass(CubeQueryConfUtil.TIME_RANGE_WRITER_CLASS, AbridgedTimeRangeWriter.class, TimeRangeWriter.class);
-    String hqlQuery = rewrite("select dim1, max(msr3)," + " msr2 from testCube" + " where " + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    String expected = getExpectedQuery(cubeName, "select testcube.dim1, max(testcube.msr3), sum(testcube.msr2) FROM ",
-      null, " GROUP BY ( testcube . dim1 )",
-      getWhereForDailyAndHourly2daysWithTimeDim(cubeName, "it", "C2_summary1"),
-      null);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
-    hqlQuery =
-      rewrite("select dim1, dim2, COUNT(msr4)," + " SUM(msr2), msr3 from testCube" + " where " + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
-    hqlQuery =
-      rewrite("select dim1, dim2, cityid, count(msr4)," + " SUM(msr2), msr3 from testCube" + " where "
-        + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
-    conf.setInt(CubeQueryConfUtil.getLookAheadPTPartsKey(UpdatePeriod.DAILY), 3);
-    hqlQuery = rewrite("select dim1, max(msr3)," + " msr2 from testCube" + " where " + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
-    hqlQuery =
-      rewrite("select dim1, dim2, COUNT(msr4)," + " SUM(msr2), msr3 from testCube" + " where " + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
-    hqlQuery =
-      rewrite("select dim1, dim2, cityid, count(msr4)," + " SUM(msr2), msr3 from testCube" + " where "
-        + twoDaysITRange, conf);
-    System.out.println("Query With process time col:" + hqlQuery);
-    // TODO compare queries
-    // compareQueries(expected, hqlQuery);
+    CubeQueryContext ctx = rewriteCtx("select dim1, max(msr3)," + " msr2 from testCube" + " where " + twoDaysITRange,
+      conf);
+    assertEquals(ctx.candidateFacts.size(), 1);
+    CandidateFact candidateFact = ctx.candidateFacts.iterator().next();
+    Set<FactPartition> partsQueried = new TreeSet<>(candidateFact.getPartsQueried());
+    Date ceilDay = DateUtil.getCeilDate(TWODAYS_BACK, DAILY);
+    Date nextDay = DateUtils.addDays(ceilDay, 1);
+    Date nextToNextDay = DateUtils.addDays(nextDay, 1);
+    HashSet<String> storageTables = Sets.newHashSet();
+    for (String storageTable : candidateFact.getStorageTables()) {
+      storageTables.add(storageTable.split("\\.")[1]);
+    }
+    TreeSet<FactPartition> expectedPartsQueried = Sets.newTreeSet();
+    for (TimePartition p : Iterables.concat(
+      TimePartition.of(HOURLY, TWODAYS_BACK).rangeUpto(TimePartition.of(HOURLY, ceilDay)),
+      TimePartition.of(DAILY, ceilDay).rangeUpto(TimePartition.of(DAILY, nextDay)),
+      TimePartition.of(HOURLY, nextDay).rangeUpto(TimePartition.of(HOURLY, NOW)))) {
+      FactPartition fp = new FactPartition("it", p, null, storageTables);
+      expectedPartsQueried.add(fp);
+    }
+    for (TimePartition it : TimePartition.of(HOURLY, ceilDay).rangeUpto(TimePartition.of(HOURLY, nextDay))) {
+      for (TimePartition pt : TimePartition.of(HOURLY, nextDay).rangeUpto(TimePartition.of(HOURLY, nextToNextDay))) {
+        FactPartition ptPartition = new FactPartition("pt", pt, null, storageTables);
+        FactPartition itPartition = new FactPartition("it", it, ptPartition, storageTables);
+        expectedPartsQueried.add(itPartition);
+      }
+    }
+    assertEquals(partsQueried, expectedPartsQueried);
+    conf.setInt(CubeQueryConfUtil.LOOK_AHEAD_PT_PARTS_PFX, 3);
+    ctx = rewriteCtx("select dim1, max(msr3)," + " msr2 from testCube" + " where " + twoDaysITRange,
+      conf);
+    partsQueried = new TreeSet<>(ctx.candidateFacts.iterator().next().getPartsQueried());
+    // pt does not exist beyond 1 day. So in this test, max look ahead possible is 3
+    assertEquals(partsQueried, expectedPartsQueried);
   }
 
   @Test


[35/50] [abbrv] lens git commit: LENS-752: Support flattening of columns selected through bridge-tables(many-to-many relationships)

Posted by ra...@apache.org.
LENS-752: Support flattening of columns selected through bridge-tables(many-to-many relationships)


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

Branch: refs/heads/current-release-line
Commit: b2c8fc02c8e194eb9b11151fc4a805b6b77d68cf
Parents: d524cc2
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Fri Sep 25 12:16:06 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Fri Sep 25 12:16:06 2015 +0530

----------------------------------------------------------------------
 lens-api/src/main/resources/cube-0.1.xsd        |   8 +
 .../apache/lens/cli/TestLensCubeCommands.java   |   2 +-
 .../apache/lens/cube/metadata/JoinChain.java    |   6 +-
 .../lens/cube/metadata/MetastoreUtil.java       |   1 +
 .../apache/lens/cube/metadata/SchemaGraph.java  |  45 ++--
 .../lens/cube/metadata/TableReference.java      |  73 ++-----
 .../lens/cube/parse/CubeQueryConfUtil.java      |   4 +
 .../apache/lens/cube/parse/JoinResolver.java    | 147 +++++++++++--
 .../src/main/resources/olap-query-conf.xml      |  16 ++
 .../apache/lens/cube/parse/CubeTestSetup.java   | 210 ++++++++++++++++++-
 .../lens/cube/parse/TestJoinResolver.java       | 193 ++++++++++++++++-
 .../apache/lens/server/metastore/JAXBUtils.java |   9 +-
 .../server/metastore/TestMetastoreService.java  |   4 +-
 src/site/apt/user/olap-cube.apt                 |  99 +++++++++
 src/site/apt/user/olap-query-conf.apt           |  44 ++--
 15 files changed, 714 insertions(+), 147 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-api/src/main/resources/cube-0.1.xsd
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/cube-0.1.xsd b/lens-api/src/main/resources/cube-0.1.xsd
index 58f68f5..5d7630d 100644
--- a/lens-api/src/main/resources/cube-0.1.xsd
+++ b/lens-api/src/main/resources/cube-0.1.xsd
@@ -521,6 +521,14 @@
   <xs:complexType name="x_table_reference">
     <xs:attribute type="xs:string" name="table" use="required"/>
     <xs:attribute type="xs:string" name="column" use="required"/>
+    <xs:attribute type="xs:boolean" name="maps_to_many" use="optional" default="false">
+      <xs:annotation>
+        <xs:documentation>
+          This boolean is used to specify if the destination reference can map to many rows for single value of source
+          reference. Mainly signifies if there are bridge tables.
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
   </xs:complexType>
 
   <xs:complexType name="x_table_references">

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
index 39441c9..b553739 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
@@ -103,7 +103,6 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
     chain1.setName("testdetailchain");
     chain1.getPaths().getPath().add(path);
     chain1.setDestTable("test_detail");
-    chains.getJoinChain().add(chain1);
     XJoinChain chain2 = new XJoinChain();
     chain2.setPaths(new XJoinPaths());
     XJoinPath path2 = new XJoinPath();
@@ -122,6 +121,7 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
     chain2.getPaths().getPath().add(path2);
     chain2.setDestTable("test_dim");
     chains.getJoinChain().add(chain2);
+    chains.getJoinChain().add(chain1);
     assertEquals(joinChains, new XJoinChainTable(chains).toString());
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/metadata/JoinChain.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/JoinChain.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/JoinChain.java
index e394e20..6250905 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/JoinChain.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/JoinChain.java
@@ -178,7 +178,8 @@ public class JoinChain implements Named {
         relationShip = new TableRelationship(from.getDestColumn(),
           client.getDimension(from.getDestTable()),
           to.getDestColumn(),
-          client.getDimension(to.getDestTable()));
+          client.getDimension(to.getDestTable()),
+          to.isMapsToMany());
       }
       return relationShip;
     }
@@ -203,7 +204,8 @@ public class JoinChain implements Named {
           relationShip = new TableRelationship(from.getDestColumn(),
             fromTable,
             to.getDestColumn(),
-            client.getDimension(to.getDestTable()));
+            client.getDimension(to.getDestTable()),
+            to.isMapsToMany());
         }
       }
       return relationShip;

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
index bf27b99..2796cd9 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/MetastoreUtil.java
@@ -130,6 +130,7 @@ public class MetastoreUtil {
     for (int i = 0; i < references.size(); i++) {
       TableReference reference = references.get(i);
       toks[i] = reference.getDestTable() + TABLE_COLUMN_SEPERATOR + reference.getDestColumn();
+      toks[i] += TABLE_COLUMN_SEPERATOR + reference.isMapsToMany();
     }
 
     return StringUtils.join(toks, ',');

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/metadata/SchemaGraph.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/SchemaGraph.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/SchemaGraph.java
index 1a37e80..fa230ef 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/SchemaGraph.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/SchemaGraph.java
@@ -22,50 +22,30 @@ import java.util.*;
 
 import org.apache.hadoop.hive.ql.metadata.HiveException;
 
-import lombok.Getter;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
 
 public class SchemaGraph {
   /*
    * An edge in the schema graph
    */
+  @Data
+  @AllArgsConstructor
+  @RequiredArgsConstructor
   public static class TableRelationship {
-    @Getter
     final String fromColumn;
-    @Getter
     final AbstractCubeTable fromTable;
-    @Getter
     final String toColumn;
-    @Getter
     final AbstractCubeTable toTable;
-
-    public TableRelationship(String fromCol, AbstractCubeTable fromTab, String toCol, AbstractCubeTable toTab) {
-      fromColumn = fromCol;
-      fromTable = fromTab;
-      toColumn = toCol;
-      toTable = toTab;
-    }
+    boolean mapsToMany = false;
 
     @Override
     public String toString() {
-      return fromTable.getName() + "." + fromColumn + "->" + toTable.getName() + "." + toColumn;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (!(obj instanceof TableRelationship)) {
-        return false;
-      }
-
-      TableRelationship other = (TableRelationship) obj;
-
-      return fromColumn.equals(other.fromColumn) && toColumn.equals(other.toColumn)
-        && fromTable.equals(other.fromTable) && toTable.equals(other.toTable);
+      return fromTable.getName() + "." + fromColumn + "->" + toTable.getName() + "." + toColumn
+        + (mapsToMany ? "[n]" : "");
     }
 
-    @Override
-    public int hashCode() {
-      return toString().hashCode();
-    }
   }
 
   /**
@@ -331,7 +311,7 @@ public class SchemaGraph {
           if (metastore.isDimension(destTableName)) {
             // Cube -> Dimension or Dimension -> Dimension reference
             Dimension relatedDim = metastore.getDimension(destTableName);
-            addLinks(refDim.getName(), cubeTable, destColumnName, relatedDim, outGraph, inGraph);
+            addLinks(refDim.getName(), cubeTable, destColumnName, relatedDim, ref.isMapsToMany(), outGraph, inGraph);
           } else {
             throw new HiveException("Dim -> Cube references are not supported: " + dim.getName() + "."
               + refDim.getName() + "->" + destTableName + "." + destColumnName);
@@ -342,9 +322,10 @@ public class SchemaGraph {
   }
 
   private void addLinks(String srcCol, AbstractCubeTable srcTbl, String destCol, AbstractCubeTable destTbl,
-    Map<AbstractCubeTable, Set<TableRelationship>> outGraph, Map<AbstractCubeTable, Set<TableRelationship>> inGraph) {
+    boolean mapsToMany, Map<AbstractCubeTable, Set<TableRelationship>> outGraph,
+    Map<AbstractCubeTable, Set<TableRelationship>> inGraph) {
 
-    TableRelationship rel = new TableRelationship(srcCol, srcTbl, destCol, destTbl);
+    TableRelationship rel = new TableRelationship(srcCol, srcTbl, destCol, destTbl, mapsToMany);
 
     Set<TableRelationship> inEdges = inGraph.get(destTbl);
     if (inEdges == null) {

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/metadata/TableReference.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TableReference.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TableReference.java
index 31fd97b..24a5fe8 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TableReference.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TableReference.java
@@ -18,80 +18,33 @@
  */
 package org.apache.lens.cube.metadata;
 
-public class TableReference {
-  private String destTable;
-  private String destColumn;
+import lombok.Data;
 
-  public TableReference() {
-  }
+@Data
+public class TableReference {
+  private final String destTable;
+  private final String destColumn;
+  private boolean mapsToMany = false;
 
   public TableReference(String destTable, String destColumn) {
+    this(destTable, destColumn, false);
+  }
+  public TableReference(String destTable, String destColumn, boolean mapsToMany) {
     this.destTable = destTable.toLowerCase();
     this.destColumn = destColumn.toLowerCase();
+    this.mapsToMany = mapsToMany;
   }
-
   public TableReference(String reference) {
     String[] desttoks = reference.split("\\.+");
     this.destTable = desttoks[0];
     this.destColumn = desttoks[1];
-  }
-
-  public String getDestTable() {
-    return destTable;
-  }
-
-  public void setDestTable(String dest) {
-    this.destTable = dest;
-  }
-
-  public String getDestColumn() {
-    return destColumn;
-  }
-
-  public void setDestColumn(String destColumn) {
-    this.destColumn = destColumn;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      return false;
-    }
-    if (getClass() != obj.getClass()) {
-      return false;
+    if (desttoks.length > 2) {
+      this.mapsToMany = Boolean.parseBoolean(desttoks[2]);
     }
-    TableReference other = (TableReference) obj;
-    if (this.getDestColumn() == null) {
-      if (other.getDestColumn() != null) {
-        return false;
-      }
-    } else if (!this.getDestColumn().equals(other.getDestColumn())) {
-      return false;
-    }
-    if (this.getDestTable() == null) {
-      if (other.getDestTable() != null) {
-        return false;
-      }
-    } else if (!this.getDestTable().equals(other.getDestTable())) {
-      return false;
-    }
-    return true;
   }
-
   @Override
   public String toString() {
-    return destTable + "." + destColumn;
+    return destTable + "." + destColumn + (mapsToMany ? "[n]" : "");
   }
 
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((destColumn == null) ? 0 : destColumn.hashCode());
-    result = prime * result + ((destTable == null) ? 0 : destTable.hashCode());
-    return result;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryConfUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryConfUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryConfUtil.java
index aab2488..87972c8 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryConfUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryConfUtil.java
@@ -104,4 +104,8 @@ public final class CubeQueryConfUtil {
   public static final Class<? extends TimeRangeWriter> DEFAULT_TIME_RANGE_WRITER = ORTimeRangeWriter.class
     .asSubclass(TimeRangeWriter.class);
   public static final String PART_WHERE_CLAUSE_DATE_FORMAT = "lens.cube.query.partition.where.clause.format";
+  public static final String ENABLE_FLATTENING_FOR_BRIDGETABLES = "lens.cube.query.enable.flattening.bridge.tables";
+  public static final boolean DEFAULT_ENABLE_FLATTENING_FOR_BRIDGETABLES = false;
+  public static final String BRIDGE_TABLE_FIELD_AGGREGATOR = "lens.cube.query.bridge.table.field.aggregator";
+  public static final String DEFAULT_BRIDGE_TABLE_FIELD_AGGREGATOR = "collect_set";
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
index c7f1e2a..a916159 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
@@ -325,11 +325,13 @@ class JoinResolver implements ContextRewriter {
     @Getter
     @Setter
     JoinClause minCostClause;
+    private final boolean flattenBridgeTables;
+    private final String bridgeTableFieldAggr;
 
     public AutoJoinContext(Map<Aliased<Dimension>, List<SchemaGraph.JoinPath>> allPaths,
       Map<Dimension, OptionalDimCtx> optionalDimensions, Map<AbstractCubeTable, String> partialJoinConditions,
       boolean partialJoinChains, Map<AbstractCubeTable, JoinType> tableJoinTypeMap, AbstractCubeTable autoJoinTarget,
-      String joinTypeCfg, boolean joinsResolved) {
+      String joinTypeCfg, boolean joinsResolved, boolean flattenBridgeTables, String bridgeTableFieldAggr) {
       this.allPaths = allPaths;
       initJoinPathColumns();
       this.partialJoinConditions = partialJoinConditions;
@@ -338,6 +340,8 @@ class JoinResolver implements ContextRewriter {
       this.autoJoinTarget = autoJoinTarget;
       this.joinTypeCfg = joinTypeCfg;
       this.joinsResolved = joinsResolved;
+      this.flattenBridgeTables = flattenBridgeTables;
+      this.bridgeTableFieldAggr = bridgeTableFieldAggr;
       log.debug("All join paths:{}", allPaths);
       log.debug("Join path from columns:{}", joinPathFromColumns);
       log.debug("Join path to columns:{}", joinPathToColumns);
@@ -429,14 +433,15 @@ class JoinResolver implements ContextRewriter {
         return fromString;
       }
       // Compute the merged join clause string for the min cost joinclause
-      String clause = getMergedJoinClause(cubeql.getAutoJoinCtx().getJoinClause(fact), dimsToQuery);
+      String clause = getMergedJoinClause(cubeql, cubeql.getAutoJoinCtx().getJoinClause(fact), dimsToQuery);
 
       fromString += clause;
       return fromString;
     }
 
     // Some refactoring needed to account for multiple join paths
-    public String getMergedJoinClause(JoinClause joinClause, Map<Dimension, CandidateDim> dimsToQuery) {
+    public String getMergedJoinClause(CubeQueryContext cubeql, JoinClause joinClause,
+                                      Map<Dimension, CandidateDim> dimsToQuery) {
       Set<String> clauses = new LinkedHashSet<String>();
       String joinTypeStr = "";
       JoinType joinType = JoinType.INNER;
@@ -452,6 +457,14 @@ class JoinResolver implements ContextRewriter {
       }
 
       Iterator<JoinTree> iter = joinClause.joinTree.dft();
+      boolean hasBridgeTable = false;
+      boolean initedBridgeClauses = false;
+      StringBuilder bridgeSelectClause = new StringBuilder();
+      StringBuilder bridgeFromClause = new StringBuilder();
+      StringBuilder bridgeFilterClause = new StringBuilder();
+      StringBuilder bridgeJoinClause = new StringBuilder();
+      StringBuilder bridgeGroupbyClause = new StringBuilder();
+
       while (iter.hasNext()) {
         JoinTree cur = iter.next();
         if (partialJoinChains) {
@@ -462,14 +475,7 @@ class JoinResolver implements ContextRewriter {
         String toAlias, fromAlias;
         fromAlias = cur.parent.getAlias();
         toAlias = cur.getAlias();
-        StringBuilder clause = new StringBuilder(joinTypeStr).append(" join ");
-        // Add storage table name followed by alias
-        clause.append(dimsToQuery.get(rel.getToTable()).getStorageString(toAlias));
-
-        clause.append(" on ").append(fromAlias).append(".")
-          .append(rel.getFromColumn()).append(" = ").append(toAlias)
-          .append(".").append(rel.getToColumn());
-
+        hasBridgeTable = flattenBridgeTables && (hasBridgeTable || rel.isMapsToMany());
         // We have to push user specified filters for the joined tables
         String userFilter = null;
         // Partition condition on the tables also needs to be pushed depending
@@ -536,14 +542,113 @@ class JoinResolver implements ContextRewriter {
             (leftStorageFilter == null ? "" : leftStorageFilter)
               + (rightStorgeFilter == null ? "" : rightStorgeFilter);
         }
+        StringBuilder clause = new StringBuilder();
+
+        // if a bridge table is present in the path
+        if (hasBridgeTable) {
+          // if any relation has bridge table, the clause becomes the following :
+          // join (" select " + joinkey + " aggr over fields from bridge table + from bridgeTable + [where user/storage
+          // filters] + groupby joinkey) on joincond"
+          // Or
+          // " join (select " + joinkey + " aggr over fields from table reached through bridge table + from bridge table
+          // join <next tables> on join condition + [and user/storage filters] + groupby joinkey) on joincond
+          if (!initedBridgeClauses) {
+            // we just found a bridge table in the path we need to initialize the clauses for subquery required for
+            // aggregating fields of bridge table
+            // initiliaze select clause with join key
+            bridgeSelectClause.append(" (select ").append(toAlias).append(".").append(rel.getToColumn()).append(" as ")
+            .append(rel.getToColumn());
+            // group by join key
+            bridgeGroupbyClause.append(" group by ").append(toAlias).append(".").append(rel.getToColumn());
+            // from clause with bridge table
+            bridgeFromClause.append(" from ").append(dimsToQuery.get(rel.getToTable()).getStorageString(toAlias));
+            // we need to initialize filter clause with user filter clause or storgae filter if applicable
+            if (StringUtils.isNotBlank(userFilter)) {
+              bridgeFilterClause.append(userFilter);
+            }
+            if (StringUtils.isNotBlank(storageFilter)) {
+              if (StringUtils.isNotBlank(bridgeFilterClause.toString())) {
+                bridgeFilterClause.append(" and ");
+              }
+              bridgeFilterClause.append(storageFilter);
+            }
+            // initialize final join clause
+            bridgeJoinClause.append(" on ").append(fromAlias).append(".")
+              .append(rel.getFromColumn()).append(" = ").append("%s")
+              .append(".").append(rel.getToColumn());
+            initedBridgeClauses = true;
+          } else {
+            // if bridge clauses are already inited, this is a next table getting joined with bridge table
+            // we will append a simple join clause
+            bridgeFromClause.append(joinTypeStr).append(" join ");
+            bridgeFromClause.append(dimsToQuery.get(rel.getToTable()).getStorageString(toAlias));
+            bridgeFromClause.append(" on ").append(fromAlias).append(".")
+              .append(rel.getFromColumn()).append(" = ").append(toAlias)
+              .append(".").append(rel.getToColumn());
 
-        if (StringUtils.isNotBlank(userFilter)) {
-          clause.append(" and ").append(userFilter);
-        }
-        if (StringUtils.isNotBlank(storageFilter)) {
-          clause.append(" and ").append(storageFilter);
+            if (StringUtils.isNotBlank(userFilter)) {
+              bridgeFromClause.append(" and ").append(userFilter);
+            }
+            if (StringUtils.isNotBlank(storageFilter)) {
+              bridgeFromClause.append(" and ").append(storageFilter);
+            }
+          }
+          if (cubeql.getTblAliasToColumns().get(toAlias) != null
+            && !cubeql.getTblAliasToColumns().get(toAlias).isEmpty()) {
+            // there are fields selected from this table after seeing bridge table in path
+            // we should make subquery for this selection
+            clause.append(joinTypeStr).append(" join ");
+            clause.append(bridgeSelectClause.toString());
+            for (String col : cubeql.getTblAliasToColumns().get(toAlias)) {
+              clause.append(",").append(bridgeTableFieldAggr).append("(").append(toAlias)
+                .append(".").append(col)
+                .append(")")
+                .append(" as ").append(col);
+            }
+            String bridgeFrom = bridgeFromClause.toString();
+            clause.append(bridgeFrom);
+            String bridgeFilter = bridgeFilterClause.toString();
+            if (StringUtils.isNotBlank(bridgeFilter)) {
+              if (bridgeFrom.contains(" join ")) {
+                clause.append(" and ");
+              } else {
+                clause.append(" where");
+              }
+              clause.append(bridgeFilter.toString());
+            }
+            clause.append(bridgeGroupbyClause.toString());
+            clause.append(") ").append(toAlias);
+            clause.append(String.format(bridgeJoinClause.toString(), toAlias));
+            clauses.add(clause.toString());
+          }
+          if (cur.getSubtrees().isEmpty()) {
+            // clear bridge flags and builders, as there are no more clauses in this tree.
+            hasBridgeTable = false;
+            initedBridgeClauses = false;
+            bridgeSelectClause.setLength(0);
+            bridgeFromClause.setLength(0);
+            bridgeFilterClause.setLength(0);
+            bridgeJoinClause.setLength(0);
+            bridgeGroupbyClause.setLength(0);
+          }
+        } else {
+          // Simple join clause is :
+          // jointype + " join " + destTable + " on " + joincond + [" and" + userfilter] + ["and" + storageFilter]
+          clause.append(joinTypeStr).append(" join ");
+          //Add storage table name followed by alias
+          clause.append(dimsToQuery.get(rel.getToTable()).getStorageString(toAlias));
+          clause.append(" on ").append(fromAlias).append(".")
+            .append(rel.getFromColumn()).append(" = ").append(toAlias)
+            .append(".").append(rel.getToColumn());
+
+          if (StringUtils.isNotBlank(userFilter)) {
+            clause.append(" and ").append(userFilter);
+          }
+          if (StringUtils.isNotBlank(storageFilter)) {
+            clause.append(" and ").append(storageFilter);
+          }
+          clauses.add(clause.toString());
         }
-        clauses.add(clause.toString());
       }
       return StringUtils.join(clauses, "");
     }
@@ -933,7 +1038,6 @@ class JoinResolver implements ContextRewriter {
   private AbstractCubeTable target;
   private HashMap<Dimension, List<JoinChain>> dimensionInJoinChain = new HashMap<Dimension, List<JoinChain>>();
 
-
   public JoinResolver(Configuration conf) {
   }
 
@@ -1105,9 +1209,14 @@ class JoinResolver implements ContextRewriter {
       multipleJoinPaths.get(aliasedDimension).addAll(
         chain.getRelationEdges(cubeql.getMetastoreClient()));
     }
+    boolean flattenBridgeTables = cubeql.getConf().getBoolean(CubeQueryConfUtil.ENABLE_FLATTENING_FOR_BRIDGETABLES,
+      CubeQueryConfUtil.DEFAULT_ENABLE_FLATTENING_FOR_BRIDGETABLES);
+    String bridgeTableFieldAggr = cubeql.getConf().get(CubeQueryConfUtil.BRIDGE_TABLE_FIELD_AGGREGATOR,
+      CubeQueryConfUtil.DEFAULT_BRIDGE_TABLE_FIELD_AGGREGATOR);
     AutoJoinContext joinCtx =
       new AutoJoinContext(multipleJoinPaths, cubeql.optionalDimensions, partialJoinConditions, partialJoinChain,
-        tableJoinTypeMap, target, cubeql.getConf().get(CubeQueryConfUtil.JOIN_TYPE_KEY), true);
+        tableJoinTypeMap, target, cubeql.getConf().get(CubeQueryConfUtil.JOIN_TYPE_KEY), true, flattenBridgeTables,
+        bridgeTableFieldAggr);
     cubeql.setAutoJoinCtx(joinCtx);
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/main/resources/olap-query-conf.xml
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/resources/olap-query-conf.xml b/lens-cube/src/main/resources/olap-query-conf.xml
index c9b8d0f..4c7b7fa 100644
--- a/lens-cube/src/main/resources/olap-query-conf.xml
+++ b/lens-cube/src/main/resources/olap-query-conf.xml
@@ -180,4 +180,20 @@
       projection wont be changed, result might include duplicate values.
     </description>
   </property>
+  <property>
+    <name>lens.cube.query.enable.flattening.bridge.tables</name>
+    <value>false</value>
+    <description>Flag specifies if fields selected have to be flattened or not, if they are coming from tables with many
+      to many relationship in join. If false, field selection will be simple join and selecting the field. If true, the
+      fields from bridge tables will be aggregated grouped by join key.
+    </description>
+  </property>
+  <property>
+    <name>lens.cube.query.bridge.table.field.aggregator</name>
+    <value>collect_set</value>
+    <description>The field aggregator function to be used for aggregating fields from bridge tables. Would be used
+      only when flattening is enabled. The value can be passed for each query. During typical deployments it would
+      be passed for each driver, as the function could be different for each driver.
+    </description>
+  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
index 67f7ab9..705f19b 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/CubeTestSetup.java
@@ -768,6 +768,9 @@ public class CubeTestSetup {
       new TableReference("testdim2", "id")));
     cubeDimensions2.add(new ReferencedDimAtrribute(new FieldSchema("dim22", "int", "ref dim"), "Dim2 refer",
       "dim2chain", "id", null, null, null));
+    cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("userid", "int", "userid")));
+    cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("xuserid", "int", "userid")));
+    cubeDimensions2.add(new BaseDimAttribute(new FieldSchema("yuserid", "int", "userid")));
 
     Map<String, String> cubeProperties = new HashMap<String, String>();
     cubeProperties.put(MetastoreUtil.getCubeTimedDimensionListKey(BASE_CUBE_NAME),
@@ -862,13 +865,67 @@ public class CubeTestSetup {
             });
           }
         });
+        add(new JoinChain("userSports", "user-sports", "user sports") {
+          {
+            addPath(new ArrayList<TableReference>() {
+              {
+                add(new TableReference("basecube", "userid"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("user_interests", "user_id", true));
+                add(new TableReference("user_interests", "sport_id"));
+                add(new TableReference("sports", "id"));
+              }
+            });
+          }
+        });
+        add(new JoinChain("userInterestIds", "user-interestsIds", "user interest ids") {
+          {
+            addPath(new ArrayList<TableReference>() {
+              {
+                add(new TableReference("basecube", "userid"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("user_interests", "user_id", true));
+              }
+            });
+          }
+        });
+        add(new JoinChain("xuserSports", "xuser-sports", "xuser sports") {
+          {
+            addPath(new ArrayList<TableReference>() {
+              {
+                add(new TableReference("basecube", "xuserid"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("user_interests", "user_id", true));
+                add(new TableReference("user_interests", "sport_id"));
+                add(new TableReference("sports", "id"));
+              }
+            });
+          }
+        });
+        add(new JoinChain("yuserSports", "user-sports", "user sports") {
+          {
+            addPath(new ArrayList<TableReference>() {
+              {
+                add(new TableReference("basecube", "yuserid"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("userdim", "id"));
+                add(new TableReference("user_interests", "user_id", true));
+                add(new TableReference("user_interests", "sport_id"));
+                add(new TableReference("sports", "id"));
+              }
+            });
+          }
+        });
       }
     };
 
     // add ref dim through chain
     cubeDimensions2.add(
-        new ReferencedDimAtrribute(new FieldSchema("cityStateCapital", "string", "State's capital thru city"),
-            "State's capital thru city", "cityState", "capital", null, null, null));
+      new ReferencedDimAtrribute(new FieldSchema("cityStateCapital", "string", "State's capital thru city"),
+        "State's capital thru city", "cityState", "capital", null, null, null));
     client.createCube(BASE_CUBE_NAME, cubeMeasures2, cubeDimensions2, exprs, joinchains, cubeProperties);
 
     Map<String, String> derivedProperties = new HashMap<String, String>();
@@ -890,6 +947,9 @@ public class CubeTestSetup {
     dimensions = new HashSet<String>();
     dimensions.add("cityid");
     dimensions.add("stateid");
+    dimensions.add("userid");
+    dimensions.add("xuserid");
+    dimensions.add("yuserid");
     dimensions.add("dim1");
     dimensions.add("dim2");
     dimensions.add("dim11");
@@ -965,7 +1025,10 @@ public class CubeTestSetup {
     factColumns.add(new FieldSchema("processing_time", "timestamp", "processing time"));
     factColumns.add(new FieldSchema("zipcode", "int", "zip"));
     factColumns.add(new FieldSchema("cityid", "int", "city id"));
-    factColumns.add(new FieldSchema("stateid", "int", "city id"));
+    factColumns.add(new FieldSchema("stateid", "int", "state id"));
+    factColumns.add(new FieldSchema("userid", "int", "user id"));
+    factColumns.add(new FieldSchema("xuserid", "int", "user id"));
+    factColumns.add(new FieldSchema("yuserid", "int", "user id"));
     factColumns.add(new FieldSchema("dim1", "string", "base dim"));
     factColumns.add(new FieldSchema("dim11", "string", "base dim"));
     factColumns.add(new FieldSchema("test_time_dim_hour_id", "int", "time id"));
@@ -985,7 +1048,9 @@ public class CubeTestSetup {
     factColumns.add(new FieldSchema("dim1", "string", "base dim"));
     factColumns.add(new FieldSchema("dim11", "string", "base dim"));
     factColumns.add(new FieldSchema("dim2", "int", "dim2 id"));
-
+    factColumns.add(new FieldSchema("userid", "int", "user id"));
+    factColumns.add(new FieldSchema("xuserid", "int", "user id"));
+    factColumns.add(new FieldSchema("yuserid", "int", "user id"));
     // create cube fact
     client.createCubeFactTable(BASE_CUBE_NAME, factName, factColumns, storageAggregatePeriods, 5L,
       factValidityProperties, storageTables);
@@ -2160,6 +2225,140 @@ public class CubeTestSetup {
     client.createCubeDimensionTable(dimName, dimTblName, dimColumns, 0L, dumpPeriods, dimProps, storageTables);
   }
 
+  private void createUserTable(CubeMetastoreClient client) throws Exception {
+    String dimName = "userdim";
+
+    Set<CubeDimAttribute> dimAttrs = new HashSet<CubeDimAttribute>();
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("id", "int", "id")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("name", "string", "name")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("age", "string", "age")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("gender", "string", "gender")));
+    Map<String, String> dimProps = new HashMap<String, String>();
+    dimProps.put(MetastoreUtil.getDimTimedDimensionKey(dimName), TestCubeMetastoreClient.getDatePartitionKey());
+    Set<JoinChain> joinChains = new HashSet<JoinChain>();
+    joinChains.add(new JoinChain("userSports", "user-sports", "user sports") {
+      {
+        addPath(new ArrayList<TableReference>() {
+          {
+            add(new TableReference("userdim", "id"));
+            add(new TableReference("user_interests", "user_id", true));
+            add(new TableReference("user_interests", "sport_id"));
+            add(new TableReference("sports", "id"));
+          }
+        });
+      }
+    });
+    Dimension userDim = new Dimension(dimName, dimAttrs, null, joinChains, dimProps,  0L);
+    client.createDimension(userDim);
+
+    String dimTblName = "usertable";
+    List<FieldSchema> dimColumns = new ArrayList<FieldSchema>();
+    dimColumns.add(new FieldSchema("id", "int", "id"));
+    dimColumns.add(new FieldSchema("name", "string", "name"));
+    dimColumns.add(new FieldSchema("age", "string", "age"));
+    dimColumns.add(new FieldSchema("gender", "string", "gender"));
+
+    Map<String, UpdatePeriod> dumpPeriods = new HashMap<String, UpdatePeriod>();
+    StorageTableDesc s1 = new StorageTableDesc();
+    s1.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s1.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    dumpPeriods.put(c1, null);
+
+    ArrayList<FieldSchema> partCols = new ArrayList<FieldSchema>();
+    List<String> timePartCols = new ArrayList<String>();
+    partCols.add(TestCubeMetastoreClient.getDatePartition());
+    timePartCols.add(TestCubeMetastoreClient.getDatePartitionKey());
+    StorageTableDesc s2 = new StorageTableDesc();
+    s2.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s2.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    s2.setPartCols(partCols);
+    s2.setTimePartCols(timePartCols);
+    dumpPeriods.put(c2, HOURLY);
+    Map<String, StorageTableDesc> storageTables = new HashMap<String, StorageTableDesc>();
+    storageTables.put(c1, s1);
+    storageTables.put(c2, s2);
+
+    client.createCubeDimensionTable(dimName, dimTblName, dimColumns, 0L, dumpPeriods, dimProps, storageTables);
+  }
+
+  private void createUserInterests(CubeMetastoreClient client) throws Exception {
+    String dimName = "user_interests";
+
+    Set<CubeDimAttribute> dimAttrs = new HashSet<CubeDimAttribute>();
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("id", "int", "id")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("user_id", "int", "user id")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("sport_id", "int", "sport id")));
+    Map<String, String> dimProps = new HashMap<String, String>();
+    dimProps.put(MetastoreUtil.getDimTimedDimensionKey(dimName), TestCubeMetastoreClient.getDatePartitionKey());
+    Dimension interestDim = new Dimension(dimName, dimAttrs, dimProps, 0L);
+    client.createDimension(interestDim);
+
+    String dimTblName = "user_interests_tbl";
+    List<FieldSchema> dimColumns = new ArrayList<FieldSchema>();
+    dimColumns.add(new FieldSchema("id", "int", "id"));
+    dimColumns.add(new FieldSchema("user_id", "int", "user id"));
+    dimColumns.add(new FieldSchema("sport_id", "int", "sport id"));
+
+    Map<String, UpdatePeriod> dumpPeriods = new HashMap<String, UpdatePeriod>();
+    StorageTableDesc s1 = new StorageTableDesc();
+    s1.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s1.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    dumpPeriods.put(c1, null);
+
+    ArrayList<FieldSchema> partCols = new ArrayList<FieldSchema>();
+    List<String> timePartCols = new ArrayList<String>();
+    partCols.add(TestCubeMetastoreClient.getDatePartition());
+    timePartCols.add(TestCubeMetastoreClient.getDatePartitionKey());
+    StorageTableDesc s2 = new StorageTableDesc();
+    s2.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s2.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    s2.setPartCols(partCols);
+    s2.setTimePartCols(timePartCols);
+    dumpPeriods.put(c2, HOURLY);
+    Map<String, StorageTableDesc> storageTables = new HashMap<String, StorageTableDesc>();
+    storageTables.put(c1, s1);
+    storageTables.put(c2, s2);
+    client.createCubeDimensionTable(dimName, dimTblName, dimColumns, 0L, dumpPeriods, dimProps, storageTables);
+  }
+
+  private void createSports(CubeMetastoreClient client) throws Exception {
+    String dimName = "sports";
+
+    Set<CubeDimAttribute> dimAttrs = new HashSet<CubeDimAttribute>();
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("id", "int", "id")));
+    dimAttrs.add(new BaseDimAttribute(new FieldSchema("name", "string", "name")));
+    Map<String, String> dimProps = new HashMap<String, String>();
+    dimProps.put(MetastoreUtil.getDimTimedDimensionKey(dimName), TestCubeMetastoreClient.getDatePartitionKey());
+    Dimension interestDim = new Dimension(dimName, dimAttrs, dimProps, 0L);
+    client.createDimension(interestDim);
+
+    String dimTblName = "sports_tbl";
+    List<FieldSchema> dimColumns = new ArrayList<FieldSchema>();
+    dimColumns.add(new FieldSchema("id", "int", "id"));
+    dimColumns.add(new FieldSchema("name", "string", "name"));
+
+    Map<String, UpdatePeriod> dumpPeriods = new HashMap<String, UpdatePeriod>();
+    StorageTableDesc s1 = new StorageTableDesc();
+    s1.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s1.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    dumpPeriods.put(c1, null);
+
+    ArrayList<FieldSchema> partCols = new ArrayList<FieldSchema>();
+    List<String> timePartCols = new ArrayList<String>();
+    partCols.add(TestCubeMetastoreClient.getDatePartition());
+    timePartCols.add(TestCubeMetastoreClient.getDatePartitionKey());
+    StorageTableDesc s2 = new StorageTableDesc();
+    s2.setInputFormat(TextInputFormat.class.getCanonicalName());
+    s2.setOutputFormat(HiveIgnoreKeyTextOutputFormat.class.getCanonicalName());
+    s2.setPartCols(partCols);
+    s2.setTimePartCols(timePartCols);
+    dumpPeriods.put(c2, HOURLY);
+    Map<String, StorageTableDesc> storageTables = new HashMap<String, StorageTableDesc>();
+    storageTables.put(c1, s1);
+    storageTables.put(c2, s2);
+
+    client.createCubeDimensionTable(dimName, dimTblName, dimColumns, 0L, dumpPeriods, dimProps, storageTables);
+  }
   public void createSources(HiveConf conf, String dbName) throws Exception {
     try {
       Database database = new Database();
@@ -2201,6 +2400,9 @@ public class CubeTestSetup {
       createStateTable(client);
       createCubeFactsWithValidColumns(client);
       createUnReachabletable(client);
+      createUserTable(client);
+      createSports(client);
+      createUserInterests(client);
     } catch (Exception exc) {
       log.error("Exception while creating sources.", exc);
       throw exc;

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
index cb63fad..7580541 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
@@ -52,6 +52,7 @@ public class TestJoinResolver extends TestQueryRewrite {
     hconf.setBoolean(CubeQueryConfUtil.DISABLE_AUTO_JOINS, false);
     hconf.setBoolean(CubeQueryConfUtil.ENABLE_GROUP_BY_TO_SELECT, true);
     hconf.setBoolean(CubeQueryConfUtil.ENABLE_SELECT_TO_GROUPBY, true);
+    hconf.setBoolean(CubeQueryConfUtil.ENABLE_FLATTENING_FOR_BRIDGETABLES, true);
     this.metastore = CubeMetastoreClient.getInstance(hconf);
   }
 
@@ -496,11 +497,13 @@ public class TestJoinResolver extends TestQueryRewrite {
     expected = getExpectedQuery("basecube",
       "select cubestatecountry.name, cubecitystatecountry.name, sum(basecube.msr2) FROM ",
       ""
-        + " join TestQueryRewrite.c1_citytable citydim on basecube.cityid = citydim.id and (citydim.dt = 'latest')"
-        + " join TestQueryRewrite.c1_statetable statedim_0 on citydim.stateid=statedim_0.id and statedim_0.dt='latest'"
-        + " join TestQueryRewrite.c1_countrytable cubecitystatecountry on statedim_0.countryid=cubecitystatecountry.id"
-        + " join TestQueryRewrite.c1_statetable statedim on basecube.stateid=statedim.id and (statedim.dt = 'latest')"
-        + " join TestQueryRewrite.c1_countrytable cubestatecountry on statedim.countryid=cubestatecountry.id "
+        + " join " + getDbName() + "c1_citytable citydim on basecube.cityid = citydim.id and (citydim.dt = 'latest')"
+        + " join " + getDbName()
+        + "c1_statetable statedim_0 on citydim.stateid=statedim_0.id and statedim_0.dt='latest'"
+        + " join " + getDbName()
+        + "c1_countrytable cubecitystatecountry on statedim_0.countryid=cubecitystatecountry.id"
+        + " join " + getDbName() + "c1_statetable statedim on basecube.stateid=statedim.id and (statedim.dt = 'latest')"
+        + " join " + getDbName() + "c1_countrytable cubestatecountry on statedim.countryid=cubestatecountry.id "
         + "", null, "group by cubestatecountry.name, cubecitystatecountry.name", null,
       getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base")
     );
@@ -752,4 +755,184 @@ public class TestJoinResolver extends TestQueryRewrite {
     assertNotNull(e2);
     assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
+
+  @Test
+  public void testBridgeTablesWithoutDimtablePartitioning() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    String query = "select usersports.name, sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join (select user_interests.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id ",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+
+  @Test
+  public void testFlattenBridgeTablesOFF() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    conf.setBoolean(CubeQueryConfUtil.ENABLE_FLATTENING_FOR_BRIDGETABLES, false);
+    String query = "select usersports.name, sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join " + getDbName() + "c1_user_interests_tbl user_interests on userdim.id = user_interests.user_id"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+
+  @Test
+  public void testFlattenBridgeTablesWithCustomAggregate() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    conf.set(CubeQueryConfUtil.BRIDGE_TABLE_FIELD_AGGREGATOR, "custom_aggr");
+    String query = "select usersports.name, sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join (select user_interests.user_id as user_id,custom_aggr(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id ",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+
+  @Test
+  public void testBridgeTablesWithMegringChains() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    String query = "select userInterestIds.sport_id, usersports.name, sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select userInterestIds.sport_id, usersports.name,"
+      + " sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim on basecube.userid = userdim.id join (select userinterestids"
+        + ".user_id as user_id,collect_set(userinterestids.sport_id) as sport_id from " + getDbName()
+        + "c1_user_interests_tbl userinterestids group by userinterestids.user_id) userinterestids on userdim.id = "
+        + "userinterestids.user_id join (select userinterestids.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl userinterestids join "
+        + getDbName() + "c1_sports_tbl usersports on userinterestids.sport_id = usersports.id"
+        + " group by userinterestids.user_id) usersports on userdim.id = usersports.user_id",
+       null, "group by userInterestIds.sport_id, usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+
+  @Test
+  public void testBridgeTablesWithMultipleFacts() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    String query = "select usersports.name, sum(msr2), sum(msr12) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected1 = getExpectedQuery("basecube", "select usersports.name name, sum(basecube.msr2) msr2 FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join (select user_interests.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id ",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    String expected2 = getExpectedQuery("basecube", "select usersports.name name, sum(basecube.msr12) msr12 FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join (select user_interests.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id ",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact2_base"));
+    TestCubeRewriter.compareContains(expected1, hqlQuery);
+    TestCubeRewriter.compareContains(expected2, hqlQuery);
+    String lower = hqlQuery.toLowerCase();
+    assertTrue(
+      lower.startsWith("select coalesce(mq1.name, mq2.name) name, mq2.msr2 msr2, mq1.msr12 msr12 from ")
+      || lower.startsWith("select coalesce(mq1.name, mq2.name) name, mq1.msr2 msr2, mq2.msr12 msr12 from "), hqlQuery);
+
+    assertTrue(hqlQuery.contains("mq1 full outer join ") && hqlQuery.endsWith("mq2 on mq1.name <=> mq2.name"),
+      hqlQuery);
+  }
+
+  @Test
+  public void testBridgeTablesWithMultipleChains() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    String query = "select usersports.name, xusersports.name, yusersports.name, sum(msr2) from basecube where "
+      + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, xusersports.name, yusersports.name,"
+      + " sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim_1 on basecube.userid = userdim_1.id "
+      + " join  (select user_interests_1.user_id as user_id, collect_set(usersports.name) as name from "
+      + getDbName() + "c1_user_interests_tbl user_interests_1 join " + getDbName() + "c1_sports_tbl usersports on "
+      + "user_interests_1.sport_id = usersports.id group by user_interests_1.user_id) "
+      + "usersports on userdim_1.id = usersports.user_id"
+      + " join " + getDbName() + "c1_usertable userdim_0 on basecube.yuserid = userdim_0.id "
+      + " join  (select user_interests_0.user_id as user_id,collect_set(yusersports.name) as name from "
+      + getDbName() + "c1_user_interests_tbl user_interests_0 join " + getDbName() + "c1_sports_tbl yusersports on "
+      + " user_interests_0.sport_id = yusersports.id group by user_interests_0.user_id) yusersports on userdim_0.id ="
+      + " yusersports.user_id join " + getDbName() + "c1_usertable userdim on basecube.xuserid = userdim.id"
+      + " join  (select user_interests.user_id as user_id,collect_set(xusersports.name) as name from "
+      + getDbName() + "c1_user_interests_tbl user_interests join " + getDbName() + "c1_sports_tbl xusersports"
+      + " on user_interests.sport_id = xusersports.id group by user_interests.user_id) xusersports on userdim.id = "
+      + " xusersports.user_id", null, "group by usersports.name, xusersports.name, yusersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+  @Test
+  public void testBridgeTablesWithDimTablePartitioning() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C2");
+    String query = "select usersports.name, sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c2_usertable userdim ON basecube.userid = userdim.id and userdim.dt='latest' "
+        + " join (select user_interests.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c2_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c2_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " and usersports.dt='latest and user_interests.dt='latest'"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id ",
+      null, "group by usersports.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c2_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
+
+  @Test
+  public void testBridgeTablesWithNormalJoins() throws Exception {
+    Configuration conf = new Configuration(hconf);
+    conf.set(CubeQueryConfUtil.DRIVER_SUPPORTED_STORAGES, "C1");
+    String query = "select usersports.name, cubestatecountry.name, cubecitystatecountry.name,"
+      + " sum(msr2) from basecube where " + TWO_DAYS_RANGE;
+    String hqlQuery = rewrite(query, conf);
+    String expected = getExpectedQuery("basecube", "select usersports.name, cubestatecountry.name, "
+      + "cubecitystatecountry.name, sum(basecube.msr2) FROM ",
+      " join " + getDbName() + "c1_usertable userdim ON basecube.userid = userdim.id "
+        + " join (select user_interests.user_id as user_id,collect_set(usersports.name) as name"
+        + " from " + getDbName() + "c1_user_interests_tbl user_interests"
+        + " join " + getDbName() + "c1_sports_tbl usersports on user_interests.sport_id = usersports.id"
+        + " group by user_interests.user_id) usersports"
+        + " on userdim.id = usersports.user_id "
+        + " join " + getDbName() + "c1_citytable citydim on basecube.cityid = citydim.id and (citydim.dt = 'latest')"
+        + " join " + getDbName()
+        + "c1_statetable statedim_0 on citydim.stateid=statedim_0.id and statedim_0.dt='latest'"
+        + " join " + getDbName()
+        + "c1_countrytable cubecitystatecountry on statedim_0.countryid=cubecitystatecountry.id"
+        + " join " + getDbName() + "c1_statetable statedim on basecube.stateid=statedim.id and (statedim.dt = 'latest')"
+        + " join " + getDbName() + "c1_countrytable cubestatecountry on statedim.countryid=cubestatecountry.id ",
+      null, "group by usersports.name, cubestatecountry.name, cubecitystatecountry.name", null,
+      getWhereForDailyAndHourly2days("basecube", "c1_testfact1_base"));
+    TestCubeRewriter.compareQueries(hqlQuery, expected);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java b/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
index ed472f6..1ed81eb 100644
--- a/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
+++ b/lens-server/src/main/java/org/apache/lens/server/metastore/JAXBUtils.java
@@ -177,7 +177,7 @@ public final class JAXBUtils {
         xd.getRefSpec().getTableReferences().getTableReference().size());
 
       for (XTableReference xRef : xd.getRefSpec().getTableReferences().getTableReference()) {
-        dimRefs.add(new TableReference(xRef.getTable(), xRef.getColumn()));
+        dimRefs.add(new TableReference(xRef.getTable(), xRef.getColumn(), xRef.isMapsToMany()));
       }
 
       hiveDim = new ReferencedDimAtrribute(new FieldSchema(xd.getName(), xd.getType().toLowerCase(),
@@ -427,6 +427,7 @@ public final class JAXBUtils {
     XTableReference xref = XCF.createXTableReference();
     xref.setTable(ref.getDestTable());
     xref.setColumn(ref.getDestColumn());
+    xref.setMapsToMany(ref.isMapsToMany());
     return xref;
   }
 
@@ -467,8 +468,9 @@ public final class JAXBUtils {
       List<TableReference> chain = new ArrayList<TableReference>(xchain.getEdges().getEdge().size() * 2);
 
       for (XJoinEdge xRef : xchain.getEdges().getEdge()) {
-        chain.add(new TableReference(xRef.getFrom().getTable(), xRef.getFrom().getColumn()));
-        chain.add(new TableReference(xRef.getTo().getTable(), xRef.getTo().getColumn()));
+        chain.add(new TableReference(xRef.getFrom().getTable(), xRef.getFrom().getColumn(),
+          xRef.getFrom().isMapsToMany()));
+        chain.add(new TableReference(xRef.getTo().getTable(), xRef.getTo().getColumn(), xRef.getTo().isMapsToMany()));
       }
       jc.addPath(chain);
     }
@@ -651,6 +653,7 @@ public final class JAXBUtils {
         XTableReference xRef = XCF.createXTableReference();
         xRef.setColumn(ref.getDestColumn());
         xRef.setTable(ref.getDestTable());
+        xRef.setMapsToMany(ref.isMapsToMany());
         xTabRefs.add(xRef);
       }
       return xTabRefs;

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
index f9be6e6..ca0fe56 100644
--- a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java
@@ -347,6 +347,7 @@ public class TestMetastoreService extends LensJerseyTest {
     XTableReference link2 = new XTableReference();
     link2.setTable("testdim");
     link2.setColumn("col1");
+    link2.setMapsToMany(true);
     XJoinEdge edge1 = cubeObjectFactory.createXJoinEdge();
     edge1.setFrom(link1);
     edge1.setTo(link2);
@@ -702,7 +703,8 @@ public class TestMetastoreService extends LensJerseyTest {
       List<TableReference> links = chain1.getPaths().get(0).getReferences();
       Assert.assertEquals(links.size(), 2);
       Assert.assertEquals(links.get(0).toString(), "testgetcube.col1");
-      Assert.assertEquals(links.get(1).toString(), "testdim.col1");
+      Assert.assertTrue(links.get(1).isMapsToMany());
+      Assert.assertEquals(links.get(1).toString(), "testdim.col1[n]");
 
       final XDerivedCube dcube = createDerivedCube("testGetDerivedCube", "testGetCube");
       target = target().path("metastore").path("cubes");

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/src/site/apt/user/olap-cube.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user/olap-cube.apt b/src/site/apt/user/olap-cube.apt
index ac91955..c47ac30 100644
--- a/src/site/apt/user/olap-cube.apt
+++ b/src/site/apt/user/olap-cube.apt
@@ -416,7 +416,106 @@ lens-shell>
 
 +---+
 
+<<Bridge tables>>
 
+* Bridge Table
+
+ A bridge table sits between a cube and a dimension or between two dimensions and is used to resolve
+ many-to-many relationships. Refer following for more details :
+
+ * {{{http://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/multivalued-dimension-bridge-table/}
+ Kimball group's definition}}
+
+ * {{{http://www.kimballgroup.com/2012/02/design-tip-142-building-bridges/} Kimball group's design tip}}
+
+ * {{{http://www.pythian.com/blog/implementing-many-to-many-relationships-in-data-warehousing/} Pythian blog}}
+
+
+ User can specify if any destination link in join-chain maps to many-many relationship during the creation of
+ cube/dimension.
+
+* Flattening feature
+
+ When we look at the following example :
+
+ User :
+
+*--+--+--+
+||ID||	Name||	Gender||
+*--+--+--+
+|1|	A|	M|
+*--+--+--+
+|2|	B|	M|
+*--+--+--+
+|3|	C|	F|
+*--+--+--+
+
+ User interests :
+
+*--+--+
+||UserID||	Sports ID||
+*--+--+
+|1|	1|
+*--+--+
+|1|	2|
+*--+--+
+|2|	1|
+*--+--+
+|2|	2|
+*--+--+
+|2|	3|
+*--+--+
+
+ Sports :
+
+*--+--+
+||SportsID||	Description||
+*--+--+
+|1|	Football|
+*--+--+
+|2|	Cricket|
+*--+--+
+|3|	Basketball|
+*--+--+
+
+ User Interests is the bridge table which is capturing the many-to-many relationship between Users and Sports.
+ And if we have a fact as follows :
+
+*--+--+
+||UserId||	Revenue||
+*--+--+
+|1|	100|
+*--+--+
+|2|	50|
+*--+--+
+
+ If analyst is interested in analyzing with respect to user's interested sport, then the report would look the
+ following :
+
+*--+--+
+||User's sport||	Revenue||
+*--+--+
+|Football|	150|
+*--+--+
+|Cricket|	150|
+*--+--+
+|BasketBall|	50|
+*--+--+
+
+ Though the individual rows are correct and the overall revenue is actually 150, looking at above report makes people
+ assume that overall revenue is 350. The flattening feature to optionally flatten the selected fields, if
+ fields involved are coming from bridge tables in join path. If flattening is enabled, the report would be the following :
+
+*--+--+
+||User Interest||	Revenue||
+*--+--+
+|Football, Cricket|	100|
+*--+--+
+|Football, Cricket, BasketBall|	50|
+*--+--+
+
+ See configuration params available at {{{./olap-query-conf.html} OLAP query configurations}} and look for config
+ related to bridge tables, for turning this on.
 
 << Query API >>
 

http://git-wip-us.apache.org/repos/asf/lens/blob/b2c8fc02/src/site/apt/user/olap-query-conf.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user/olap-query-conf.apt b/src/site/apt/user/olap-query-conf.apt
index 8204c34..6606d42 100644
--- a/src/site/apt/user/olap-query-conf.apt
+++ b/src/site/apt/user/olap-query-conf.apt
@@ -24,44 +24,48 @@ OLAP query configuration
 *--+--+---+--+
 |<<No.>>|<<Property Name>>|<<Default Value>>|<<Description>>|
 *--+--+---+--+
-|1|lens.cube.query.disable.aggregate.resolver|true|Tells whether to disable automatic resolution of aggregations for measures in a cube. To enable automatic resolution, this value should be false.|
+|1|lens.cube.query.bridge.table.field.aggregator|collect_set|The field aggregator function to be used for aggregating fields from bridge tables. Would be used only when flattening is enabled. The value can be passed for each query. During typical deployments it would be passed for each driver, as the function could be different for each driver.|
 *--+--+---+--+
-|2|lens.cube.query.disable.auto.join|true|Tells whether to disable automatic resolution of join conditions between tables involved. To enable automatic resolution, this value should be false.|
+|2|lens.cube.query.disable.aggregate.resolver|true|Tells whether to disable automatic resolution of aggregations for measures in a cube. To enable automatic resolution, this value should be false.|
 *--+--+---+--+
-|3|lens.cube.query.driver.supported.storages| |List of comma separated storage names that supported by a driver. If no value is specified, all storages are valid|
+|3|lens.cube.query.disable.auto.join|true|Tells whether to disable automatic resolution of join conditions between tables involved. To enable automatic resolution, this value should be false.|
 *--+--+---+--+
-|4|lens.cube.query.enable.attrfields.add.distinct|true|When the query has only attribute fields projected from cube and the flag is set to true, distinct clause will be added for the projection so that no duplicate values will be projected. If flag is set to false, projection wont be changed, result might include duplicate values.|
+|4|lens.cube.query.driver.supported.storages| |List of comma separated storage names that supported by a driver. If no value is specified, all storages are valid|
 *--+--+---+--+
-|5|lens.cube.query.fail.if.data.partial|false|Whether to fail the query of data is partial|
+|5|lens.cube.query.enable.attrfields.add.distinct|true|When the query has only attribute fields projected from cube and the flag is set to true, distinct clause will be added for the projection so that no duplicate values will be projected. If flag is set to false, projection wont be changed, result might include duplicate values.|
 *--+--+---+--+
-|6|lens.cube.query.join.type|INNER|Tells what the join type is, in-case of automatic resolution of joins is enabled|
+|6|lens.cube.query.enable.flattening.bridge.tables|false|Flag specifies if fields selected have to be flattened or not, if they are coming from tables with many to many relationship in join. If false, field selection will be simple join and selecting the field. If true, the fields from bridge tables will be aggregated grouped by join key.|
 *--+--+---+--+
-|7|lens.cube.query.lookahead.ptparts.forinterval.${interval}|1|The value of number of lookahead process time partitions for interval specified. Interval can be any Update period.|
+|7|lens.cube.query.fail.if.data.partial|false|Whether to fail the query of data is partial|
 *--+--+---+--+
-|8|lens.cube.query.max.interval| |Maximum value of the update period that the query timed dimensions can take values of. For example, if query involves month ranges, user can say query maximum interval is daily, then no monthly partitions will be picked.|
+|8|lens.cube.query.join.type|INNER|Tells what the join type is, in-case of automatic resolution of joins is enabled|
 *--+--+---+--+
-|9|lens.cube.query.nonexisting.partitions| |The list of comma separated non existing partitions, if query can run with partial data. The value will be set by the cube query rewriter|
+|9|lens.cube.query.lookahead.ptparts.forinterval.${interval}|1|The value of number of lookahead process time partitions for interval specified. Interval can be any Update period.|
 *--+--+---+--+
-|10|lens.cube.query.partition.where.clause.format| |The simple date format of how the queried partition should be put in where clause. If nothing is specified, it will use the format from org.apache.lens.cube.metadata.UpdatePeriod for each type of partition|
+|10|lens.cube.query.max.interval| |Maximum value of the update period that the query timed dimensions can take values of. For example, if query involves month ranges, user can say query maximum interval is daily, then no monthly partitions will be picked.|
 *--+--+---+--+
-|11|lens.cube.query.pick.lightest.fact.first|false|If set to true, lightest fact will be resolved first than resolving storages. Otherwise, storages will be resolved to check all partitions exist and then pick lightest fact among candidates|
+|11|lens.cube.query.nonexisting.partitions| |The list of comma separated non existing partitions, if query can run with partial data. The value will be set by the cube query rewriter|
 *--+--+---+--+
-|12|lens.cube.query.process.time.partition.column| |The column name which is a process time column. If process time column is specified, query rewriter will look ahead the partitions of other timed dimensions inside this column.|
+|12|lens.cube.query.partition.where.clause.format| |The simple date format of how the queried partition should be put in where clause. If nothing is specified, it will use the format from org.apache.lens.cube.metadata.UpdatePeriod for each type of partition|
 *--+--+---+--+
-|13|lens.cube.query.promote.groupby.toselect|false|Tells whether to promote group by clauses to be promoted to select expressions if they are already not projected. To enable automatic promotion, this value should be true.|
+|13|lens.cube.query.pick.lightest.fact.first|false|If set to true, lightest fact will be resolved first than resolving storages. Otherwise, storages will be resolved to check all partitions exist and then pick lightest fact among candidates|
 *--+--+---+--+
-|14|lens.cube.query.promote.select.togroupby|false|Tells whether to promote select expressions which is not inside any aggregate, to be promoted to groupby clauses, if they are already not part of groupby clauses. To enable automatic promotion, this value should be true.|
+|14|lens.cube.query.process.time.partition.column| |The column name which is a process time column. If process time column is specified, query rewriter will look ahead the partitions of other timed dimensions inside this column.|
 *--+--+---+--+
-|15|lens.cube.query.replace.timedim|true|Tells whether timedim attribute queried in the time range should be replaced with its corresponding partition column name.|
+|15|lens.cube.query.promote.groupby.toselect|false|Tells whether to promote group by clauses to be promoted to select expressions if they are already not projected. To enable automatic promotion, this value should be true.|
 *--+--+---+--+
-|16|lens.cube.query.time.range.writer.class|org.apache.lens.cube.parse.ORTimeRangeWriter|The timerange writer class which specifies how the resolved partitions in timeranges should be written in final query. Available writers are org.apache.lens.cube.parse.ORTimeRangeWriter and org.apache.lens.cube.parse.BetweenTimeRangeWriter|
+|16|lens.cube.query.promote.select.togroupby|false|Tells whether to promote select expressions which is not inside any aggregate, to be promoted to groupby clauses, if they are already not part of groupby clauses. To enable automatic promotion, this value should be true.|
 *--+--+---+--+
-|17|lens.cube.query.valid.${cubename}.facttables| |List of comma separated fact tables that are valid for cube. If no value is specified, all fact tables are valid|
+|17|lens.cube.query.replace.timedim|true|Tells whether timedim attribute queried in the time range should be replaced with its corresponding partition column name.|
 *--+--+---+--+
-|18|lens.cube.query.valid.dim.storgaetables| |List of comma separated dimension storage tables that are valid. If no value is specified, all tables are valid|
+|18|lens.cube.query.time.range.writer.class|org.apache.lens.cube.parse.ORTimeRangeWriter|The timerange writer class which specifies how the resolved partitions in timeranges should be written in final query. Available writers are org.apache.lens.cube.parse.ORTimeRangeWriter and org.apache.lens.cube.parse.BetweenTimeRangeWriter|
 *--+--+---+--+
-|19|lens.cube.query.valid.fact.${facttable}.storage.${storagename}.updateperiods| |List of comma separated update periods that are valid for a fact on a storage. If no value is specified, all update periods are valid|
+|19|lens.cube.query.valid.${cubename}.facttables| |List of comma separated fact tables that are valid for cube. If no value is specified, all fact tables are valid|
 *--+--+---+--+
-|20|lens.cube.query.valid.fact.${facttable}.storagetables| |List of comma separated storage tables that are valid for a fact. If no value is specified, all storage tables are valid|
+|20|lens.cube.query.valid.dim.storgaetables| |List of comma separated dimension storage tables that are valid. If no value is specified, all tables are valid|
+*--+--+---+--+
+|21|lens.cube.query.valid.fact.${facttable}.storage.${storagename}.updateperiods| |List of comma separated update periods that are valid for a fact on a storage. If no value is specified, all update periods are valid|
+*--+--+---+--+
+|22|lens.cube.query.valid.fact.${facttable}.storagetables| |List of comma separated storage tables that are valid for a fact. If no value is specified, all storage tables are valid|
 *--+--+---+--+
 The configuration parameters and their default values


[46/50] [abbrv] lens git commit: LENS-797: Improve CLI documentation to mention the helpful role of pressing tab while writing commands

Posted by ra...@apache.org.
LENS-797: Improve CLI documentation to mention the helpful role of pressing tab while writing commands


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/2d7948d7
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/2d7948d7
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/2d7948d7

Branch: refs/heads/current-release-line
Commit: 2d7948d725a4c0444ac04e958e9b2a7ccf2dc59b
Parents: 7080b76
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Thu Oct 8 15:17:23 2015 +0530
Committer: Raju Bairishetti <ra...@im0933-x0.corp.inmobi.com>
Committed: Thu Oct 8 15:17:23 2015 +0530

----------------------------------------------------------------------
 .../cli/commands/LensConnectionCommands.java    |  2 +-
 .../lens/cli/commands/LensCubeCommands.java     |  2 +-
 .../lens/cli/commands/LensDatabaseCommands.java |  3 +-
 .../cli/commands/LensDimensionCommands.java     |  3 +-
 .../commands/LensDimensionTableCommands.java    |  2 +-
 .../lens/cli/commands/LensFactCommands.java     |  2 +-
 .../cli/commands/LensLogResourceCommands.java   | 17 ++++----
 .../cli/commands/LensNativeTableCommands.java   |  2 +-
 .../lens/cli/commands/LensQueryCommands.java    |  2 +-
 .../lens/cli/commands/LensStorageCommands.java  |  2 +-
 lens-cli/src/test/resources/cli-intro.apt       | 23 +++++++---
 src/site/apt/user/cli.apt                       | 45 ++++++++++++--------
 12 files changed, 65 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java
index 2795211..0aa51a8 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java
@@ -49,7 +49,7 @@ import lombok.extern.slf4j.Slf4j;
  */
 @Slf4j
 @Component
-@UserDocumentation(title = "Session management",
+@UserDocumentation(title = "Commands for Session Management",
   description = "Opening the lens CLI shell is equivalent to open a session with lens server."
     + "This section provides all the commands available for in shell which are applicable for the full session.")
 public class LensConnectionCommands extends BaseLensCommand {

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
index 0afdd61..5211d76 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
@@ -36,7 +36,7 @@ import lombok.NonNull;
  * The Class LensCubeCommands.
  */
 @Component
-@UserDocumentation(title = "OLAP Data cube metadata management",
+@UserDocumentation(title = "Commands for OLAP Data Cube Management",
   description = "These commands provide CRUD for cubes")
 public class LensCubeCommands extends ConceptualTableCrudCommand<XCube> {
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
index 1de24a4..05108f0 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java
@@ -31,7 +31,8 @@ import org.springframework.stereotype.Component;
  * The Class LensDatabaseCommands.
  */
 @Component
-@UserDocumentation(title = "Database management commands", description = "These commands provide CRUD for databases")
+@UserDocumentation(title = "Commands for Database Management",
+  description = "These commands provide CRUD for databases")
 public class LensDatabaseCommands extends LensCRUDCommand {
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
index cd7de55..dc8349e 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
@@ -36,7 +36,8 @@ import lombok.NonNull;
  * The Class LensDimensionCommands.
  */
 @Component
-@UserDocumentation(title = "Dimension Management", description = "These commands provide CRUD for Dimensions")
+@UserDocumentation(title = "Commands for Dimension Management",
+  description = "These commands provide CRUD for Dimensions")
 public class LensDimensionCommands extends ConceptualTableCrudCommand<XDimension> {
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
index 74efed9..7df5c7c 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
@@ -38,7 +38,7 @@ import lombok.NonNull;
  * The Class LensDimensionTableCommands.
  */
 @Component
-@UserDocumentation(title = "Commands for Dimension Tables",
+@UserDocumentation(title = "Commands for Dimension Tables Management",
   description = "These commands provide CRUD for dimension tables, associated storages, and fact partitions")
 public class LensDimensionTableCommands extends LogicalTableCrudCommand<XDimensionTable>
   implements CommandMarker {

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
index 6d7d9eb..6457bce 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
@@ -37,7 +37,7 @@ import lombok.NonNull;
  * The Class LensFactCommands.
  */
 @Component
-@UserDocumentation(title = "Management of Facts",
+@UserDocumentation(title = "Commands for Facts Management",
   description = "These command provide CRUD for facts, associated storages, and fact partitions")
 public class LensFactCommands extends LogicalTableCrudCommand<XFactTable> {
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensLogResourceCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensLogResourceCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensLogResourceCommands.java
index c43a5ff..59b7355 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensLogResourceCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensLogResourceCommands.java
@@ -40,29 +40,30 @@ import org.springframework.stereotype.Component;
  * SUSPEND CHECKSTYLE CHECK InnerAssignmentCheck
  */
 @Component
-@UserDocumentation(title = "Access to Log Resouces",
+@UserDocumentation(title = "Commands for Accessing Logs",
   description = "This section provides commands for fetching logs under LENS_LOG_DIR.")
 public class LensLogResourceCommands extends BaseLensCommand {
 
-  @CliCommand(value = "show logs", help = "show logs for a given query handle or log file")
+  @CliCommand(value = "show logs",
+    help = "show logs for the given handle <log_handle>. Handle can either be a query handle or request id. "
+      + "You can optionally provide a location to save the logs as <save_location>")
   public String getLogs(
-    @CliOption(key = {"", "log_handle"}, mandatory = true, help = "log handle can be be query_handle for queries")
+    @CliOption(key = {"", "log_handle"}, mandatory = true, help = "<log_handle>")
     String logFile, @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") String location) {
     try {
       Response response = getClient().getLogs(logFile);
       if (response.getStatus() == Response.Status.OK.getStatusCode()) {
         if (StringUtils.isBlank(location)) {
           OutputStream outStream = new PrintStream(System.out, true, "UTF-8");
-          try (InputStream stream = response.readEntity(InputStream.class);) {
+          try (InputStream stream = response.readEntity(InputStream.class)) {
             IOUtils.copy(stream, outStream);
             return "printed complete log content";
           }
         } else {
-          location = getValidPath(new File(location), true, true);
-          String fileName = logFile;
-          location = getValidPath(new File(location + File.separator + fileName), false, false);
+          String existingDirectoryLocation = getValidPath(new File(location), true, true);
+          location = getValidPath(new File(existingDirectoryLocation + File.separator + logFile), false, false);
           try (InputStream stream = response.readEntity(InputStream.class);
-              FileOutputStream outStream = new FileOutputStream(new File(location));) {
+              FileOutputStream outStream = new FileOutputStream(new File(location))) {
             IOUtils.copy(stream, outStream);
             return "Saved to " + location;
           }

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensNativeTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensNativeTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensNativeTableCommands.java
index df42581..32706cf 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensNativeTableCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensNativeTableCommands.java
@@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
  * The Class LensNativeTableCommands.
  */
 @Component
-@UserDocumentation(title = "Native Table management", description = "Read operations on native tables")
+@UserDocumentation(title = "Commands for Native Table Management", description = "Read operations on native tables")
 public class LensNativeTableCommands extends LensCRUDCommand<XNativeTable> {
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index b6e3fcf..096fd7a 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -49,7 +49,7 @@ import com.google.common.base.Joiner;
  * SUSPEND CHECKSTYLE CHECK InnerAssignmentCheck
  */
 @Component
-@UserDocumentation(title = "Query Management",
+@UserDocumentation(title = "Commands for Query Management",
   description = "This section provides commands for query life cycle - "
     + "submit, check status,\n"
     + "  fetch results, kill or list all the queries. Also provides commands for\n"

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/main/java/org/apache/lens/cli/commands/LensStorageCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensStorageCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensStorageCommands.java
index ca73af7..bbda077 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensStorageCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensStorageCommands.java
@@ -36,7 +36,7 @@ import lombok.NonNull;
  * The Class LensStorageCommands.
  */
 @Component
-@UserDocumentation(title = "Storage Management", description = "These commands provide CRUD for Storages")
+@UserDocumentation(title = "Commands for Storage Management", description = "These commands provide CRUD for Storages")
 public class LensStorageCommands extends LensCRUDCommand<XStorage> implements CommandMarker {
 
   @CliCommand(value = "show storages", help = "list all storages")

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/lens-cli/src/test/resources/cli-intro.apt
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/resources/cli-intro.apt b/lens-cli/src/test/resources/cli-intro.apt
index b5773ab..387e9e1 100644
--- a/lens-cli/src/test/resources/cli-intro.apt
+++ b/lens-cli/src/test/resources/cli-intro.apt
@@ -54,12 +54,6 @@ User CLI Commands
   with <<<arg3>>>. arg4 can be omitted, or if passed, it has to be passed with <<<--arg4>>>.
 
 
-=========================
-
-
-* LENS Commands
-
-
 ** Argument Passing in LENS
 
   Lens supports both the approaches of passing arguments but advises the usage of keyword arguments over list arguments.
@@ -72,7 +66,24 @@ User CLI Commands
   * Arguments are of any type, but there is only one argument of type arg2 or arg3 and that's the argument you intend
      to pass value to.
 
+
+** About the huge number of commands below
+
+  The commands given below is an exhaustive list of commands available in lens cli. The good thing is, you probably
+  don't need to remember any of them. In lens-cli, pressing <<<tab>>> anytime will give you possible keywords.
+  For example, if you don't know the exact command but have an idea that it's related to facts,
+  type fact and press <<<tab>>>. You'll be provided with all possible next keywords.
+  Looking at the options should be helpful to know which to pick
+  for the action you want to perform. Similarly, when you don't know what arguments the command takes, type <<<-->>>
+  and then <<<tab>>> will also provide you with with the arguments of the command.
+  Also, there's a special command <<<help>>> which displays all possible commands with the arguments they expect.
+
+
 ** Known bugs
 
   * If all arguments have same value, Something weird will happen.
 
+================
+
+* LENS CLI Commands
+

http://git-wip-us.apache.org/repos/asf/lens/blob/2d7948d7/src/site/apt/user/cli.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user/cli.apt b/src/site/apt/user/cli.apt
index be93b8c..c266c6d 100644
--- a/src/site/apt/user/cli.apt
+++ b/src/site/apt/user/cli.apt
@@ -54,12 +54,6 @@ User CLI Commands
   with <<<arg3>>>. arg4 can be omitted, or if passed, it has to be passed with <<<--arg4>>>.
 
 
-=========================
-
-
-* LENS Commands
-
-
 ** Argument Passing in LENS
 
   Lens supports both the approaches of passing arguments but advises the usage of keyword arguments over list arguments.
@@ -72,14 +66,31 @@ User CLI Commands
   * Arguments are of any type, but there is only one argument of type arg2 or arg3 and that's the argument you intend
      to pass value to.
 
+
+** About the huge number of commands below
+
+  The commands given below is an exhaustive list of commands available in lens cli. The good thing is, you probably
+  don't need to remember any of them. In lens-cli, pressing <<<tab>>> anytime will give you possible keywords.
+  For example, if you don't know the exact command but have an idea that it's related to facts,
+  type fact and press <<<tab>>>. You'll be provided with all possible next keywords.
+  Looking at the options should be helpful to know which to pick
+  for the action you want to perform. Similarly, when you don't know what arguments the command takes, type <<<-->>>
+  and then <<<tab>>> will also provide you with with the arguments of the command.
+  Also, there's a special command <<<help>>> which displays all possible commands with the arguments they expect.
+
+
 ** Known bugs
 
   * If all arguments have same value, Something weird will happen.
 
+================
+
+* LENS CLI Commands
+
 
 
 
-** Session management
+** Commands for Session Management
 
   Opening the lens CLI shell is equivalent to open a session with lens server.This section provides all the commands available for in shell which are applicable for the full session.
 
@@ -114,7 +125,7 @@ User CLI Commands
 
 ===
 
-** Database management commands
+** Commands for Database Management
 
   These commands provide CRUD for databases
 
@@ -133,7 +144,7 @@ User CLI Commands
 
 ===
 
-** Storage Management
+** Commands for Storage Management
 
   These commands provide CRUD for Storages
 
@@ -154,7 +165,7 @@ User CLI Commands
 
 ===
 
-** OLAP Data cube metadata management
+** Commands for OLAP Data Cube Management
 
   These commands provide CRUD for cubes
 
@@ -181,7 +192,7 @@ User CLI Commands
 
 ===
 
-** Dimension Management
+** Commands for Dimension Management
 
   These commands provide CRUD for Dimensions
 
@@ -206,7 +217,7 @@ User CLI Commands
 
 ===
 
-** Management of Facts
+** Commands for Facts Management
 
   These command provide CRUD for facts, associated storages, and fact partitions
 
@@ -251,7 +262,7 @@ User CLI Commands
 
 ===
 
-** Commands for Dimension Tables
+** Commands for Dimension Tables Management
 
   These commands provide CRUD for dimension tables, associated storages, and fact partitions
 
@@ -294,7 +305,7 @@ User CLI Commands
 
 ===
 
-** Native Table management
+** Commands for Native Table Management
 
   Read operations on native tables
 
@@ -309,7 +320,7 @@ User CLI Commands
 
 ===
 
-** Query Management
+** Commands for Query Management
 
   This section provides commands for query life cycle - submit, check status,
   fetch results, kill or list all the queries. Also provides commands for
@@ -354,14 +365,14 @@ User CLI Commands
 
 ===
 
-** Access to Log Resouces
+** Commands for Accessing Logs
 
   This section provides commands for fetching logs under LENS_LOG_DIR.
 
 *--+--+
 |<<Command>>|<<Description>>|
 *--+--+
-|show logs [--log_handle] log handle can be be query_handle for queries [--save_location \<save_location\>]|show logs for a given query handle or log file|
+|show logs [--log_handle] \<log_handle\> [--save_location \<save_location\>]|show logs for the given handle <<<log_handle>>>. Handle can either be a query handle or request id. You can optionally provide a location to save the logs as <<<save_location>>>|
 *--+--+
   <<Lens Log Resource Commands>>
 


[50/50] [abbrv] lens git commit: LENS-782: UI support for the saved, parametrized query feature

Posted by ra...@apache.org.
LENS-782: UI support for the saved, parametrized query feature


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

Branch: refs/heads/current-release-line
Commit: 867142113fbbe2d0793e7da156cc4ef190c22811
Parents: dd33a60
Author: Ankeet Maini <an...@gmail.com>
Authored: Thu Oct 8 22:25:12 2015 +0530
Committer: raju <ra...@apache.org>
Committed: Thu Oct 8 22:25:12 2015 +0530

----------------------------------------------------------------------
 lens-ui/app/actions/AdhocQueryActions.js        | 179 ++++++-
 lens-ui/app/adapters/AdhocQueryAdapter.js       |  80 +++-
 lens-ui/app/adapters/BaseAdapter.js             |  93 ++--
 lens-ui/app/adapters/XMLAdapter.js              |  37 ++
 lens-ui/app/app.js                              |  30 +-
 lens-ui/app/components/AdhocQueryComponent.js   |  42 +-
 lens-ui/app/components/AppComponent.js          |   9 +-
 lens-ui/app/components/CubeSchemaComponent.js   |  36 +-
 lens-ui/app/components/CubeTreeComponent.js     |  42 +-
 lens-ui/app/components/DatabaseComponent.js     |  18 +-
 lens-ui/app/components/HeaderComponent.js       |  37 +-
 lens-ui/app/components/LoaderComponent.js       |   2 +-
 lens-ui/app/components/LoginComponent.js        |  24 +-
 lens-ui/app/components/LogoutComponent.js       |   5 +-
 lens-ui/app/components/QueryBoxComponent.js     | 469 ++++++++++++++-----
 .../components/QueryDetailResultComponent.js    |  37 +-
 .../app/components/QueryOperationsComponent.js  |  21 +-
 .../app/components/QueryParamRowComponent.js    | 173 +++++++
 lens-ui/app/components/QueryParamsComponent.js  | 130 +++++
 lens-ui/app/components/QueryPreviewComponent.js |  57 ++-
 lens-ui/app/components/QueryResultsComponent.js |  25 +-
 .../RequireAuthenticationComponent.js           |   4 +-
 lens-ui/app/components/SavedQueriesComponent.js | 180 +++++++
 .../components/SavedQueryPreviewComponent.js    | 136 ++++++
 lens-ui/app/components/SidebarComponent.js      |   4 +-
 lens-ui/app/components/TableSchemaComponent.js  |  34 +-
 lens-ui/app/components/TableTreeComponent.js    |  47 +-
 lens-ui/app/constants/AdhocQueryConstants.js    |  11 +-
 lens-ui/app/constants/AppConstants.js           |   5 +-
 lens-ui/app/dispatcher/AppDispatcher.js         |   1 -
 lens-ui/app/stores/AdhocQueryStore.js           |  23 +-
 lens-ui/app/stores/CubeStore.js                 |   3 +-
 lens-ui/app/stores/DatabaseStore.js             |   4 +-
 lens-ui/app/stores/SavedQueryStore.js           |  99 ++++
 lens-ui/app/stores/TableStore.js                |   4 +-
 lens-ui/app/stores/UserStore.js                 |  16 +-
 lens-ui/app/styles/css/global.css               |  22 +
 lens-ui/app/styles/css/login.css                |   3 +-
 lens-ui/app/styles/css/query-component.css      |   3 +-
 lens-ui/app/styles/css/tree.css                 |   3 +-
 lens-ui/app/styles/less/globals.less            |   3 +-
 lens-ui/app/utils/ErrorParser.js                |  53 +++
 lens-ui/index.html                              |   1 +
 lens-ui/package.json                            |  23 +-
 lens-ui/server.js                               |  39 +-
 lens-ui/webpack.config.js                       |  22 +-
 46 files changed, 1760 insertions(+), 529 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/actions/AdhocQueryActions.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/actions/AdhocQueryActions.js b/lens-ui/app/actions/AdhocQueryActions.js
index 8c2d109..284c781 100644
--- a/lens-ui/app/actions/AdhocQueryActions.js
+++ b/lens-ui/app/actions/AdhocQueryActions.js
@@ -20,6 +20,48 @@
 import AppDispatcher from '../dispatcher/AppDispatcher';
 import AdhocQueryConstants from '../constants/AdhocQueryConstants';
 import AdhocQueryAdapter from '../adapters/AdhocQueryAdapter';
+import ErrorParser from '../utils/ErrorParser';
+import _ from 'lodash';
+
+function _executeQuery (secretToken, query, queryName) {
+  AdhocQueryAdapter.executeQuery(secretToken, query, queryName)
+    .then(queryHandle => {
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE,
+        payload: { queryHandle: queryHandle }
+      });
+    }, (error) => {
+      // error details contain array of objects {code, message}
+      var errorDetails = ErrorParser.getMessage(error);
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
+        payload: {
+          type: 'Error',
+          texts: errorDetails
+        }
+      });
+    });
+}
+
+function _saveQuery (secretToken, user, query, options) {
+  AdhocQueryAdapter.saveQuery(secretToken, user, query, options)
+    .then(response => {
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.SAVE_QUERY_SUCCESS,
+        payload: {
+          type: 'Success',
+          text: 'Query was successfully saved!',
+          id: response.id
+        }
+      });
+    }, error => {
+      error = error.error;
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.SAVE_QUERY_FAILED,
+        payload: {type: 'Error', text: error.code + ': ' + error.message}
+      });
+    }).catch(e => { console.error(e); });
+}
 
 let AdhocQueryActions = {
   getDatabases (secretToken) {
@@ -30,7 +72,6 @@ let AdhocQueryActions = {
           payload: { databases: databases }
         });
       }, function (error) {
-
         AppDispatcher.dispatch({
           actionType: AdhocQueryConstants.RECEIVE_DATABASES_FAILED,
           payload: {
@@ -49,7 +90,6 @@ let AdhocQueryActions = {
           payload: { cubes: cubes }
         });
       }, function (error) {
-
         // propagating the error message, couldn't fetch cubes
         AppDispatcher.dispatch({
           actionType: AdhocQueryConstants.RECEIVE_CUBES_FAILED,
@@ -61,22 +101,117 @@ let AdhocQueryActions = {
       });
   },
 
-  executeQuery (secretToken, query, queryName) {
-    AdhocQueryAdapter.executeQuery(secretToken, query, queryName)
-      .then(function (queryHandle) {
+  getSavedQueries (secretToken, user, options) {
+    AdhocQueryAdapter.getSavedQueries(secretToken, user, options)
+      .then(savedQueries => {
         AppDispatcher.dispatch({
-          actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE,
-          payload: { queryHandle: queryHandle }
+          actionType: AdhocQueryConstants.RECEIVE_SAVED_QUERIES,
+          payload: savedQueries
         });
-      }, function (error) {
+      });
+  },
+
+  getSavedQueryById (secretToken, id) {
+    AdhocQueryAdapter.getSavedQueryById(secretToken, id)
+      .then(savedQuery => {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_SAVED_QUERY,
+          payload: savedQuery
+        });
+      });
+  },
+
+  updateSavedQuery (secretToken, user, query, options, id) {
+    AdhocQueryAdapter.getParams(secretToken, query).then(response => {
+      let serverParams = response.parameters
+        .map(item => item.name)
+        .sort();
+      let clientParams = options && options.parameters && options.parameters
+        .map(item => item.name)
+        .sort();
+      if (!clientParams) clientParams = [];
+      if (_.isEqual(serverParams, clientParams)) {
+        AdhocQueryAdapter.updateSavedQuery(secretToken, user, query, options, id)
+          .then(response => {
+            AppDispatcher.dispatch({
+              actionType: AdhocQueryConstants.SAVE_QUERY_SUCCESS,
+              payload: {
+                type: 'Success',
+                text: 'Query was successfully updated!',
+                id: response.id
+              }
+            });
+          }, error => {
+            error = error.error;
+            AppDispatcher.dispatch({
+              actionType: AdhocQueryConstants.SAVE_QUERY_FAILED,
+              payload: {type: 'Error', text: error.code + ': ' + error.message}
+            });
+          }).catch(e => { console.error(e); });
+      } else {
+        // get parameters' meta
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_PARAMS_META,
+          payload: response.parameters
+        });
+      }
+    });
+  },
+
+  saveQuery (secretToken, user, query, options) {
+    AdhocQueryAdapter.getParams(secretToken, query).then(response => {
+      let serverParams = response.parameters
+        .map(item => item.name)
+        .sort();
+      let clientParams = options && options.parameters && options.parameters
+        .map(item => item.name)
+        .sort();
+      if (!clientParams) clientParams = [];
+      if (_.isEqual(serverParams, clientParams)) {
+        _saveQuery(secretToken, user, query, options);
+      } else {
+        // get parameters' meta
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_PARAMS_META,
+          payload: response.parameters
+        });
+      }
+    }, error => {
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
+        payload: {
+          type: 'Error',
+          text: 'Please enable Saved Queries feature in the LENS Server to proceed.'
+        }
+      });
+    });
+  },
+
+  // first calls parameters API and sees if the query has any params,
+  // as we can't run a query with params, it needs to be saved first.
+  runQuery (secretToken, query, queryName) {
+    AdhocQueryAdapter.getParams(secretToken, query).then(response => {
+      if (!response.parameters.length) {
+        _executeQuery(secretToken, query, queryName);
+      } else {
+        // ask user to save the query maybe?
         AppDispatcher.dispatch({
           actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
           payload: {
-            responseCode: error.status,
-            responseMessage: error.statusText
+            type: 'Error',
+            text: 'You can\'t run a query with parameters, save it first.'
           }
         });
+      }
+    }, error => {
+      AppDispatcher.dispatch({
+        actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
+        payload: {
+          type: 'Error',
+          text: 'Please enable Saved Queries feature in the LENS Server to proceed.'
+        }
       });
+    });
   },
 
   getCubeDetails (secretToken, cubeName) {
@@ -138,11 +273,9 @@ let AdhocQueryActions = {
       .then(function (result) {
         let payload;
         if (Object.prototype.toString.call(result).match('String')) {
-
           // persistent
           payload = { downloadURL: result, type: 'PERSISTENT', handle: handle };
         } else if (Object.prototype.toString.call(result).match('Array')) {
-
           // in-memory gives array
           payload = {
             queryResult: result[0],
@@ -174,7 +307,6 @@ let AdhocQueryActions = {
           payload: { tables: tables, database: database }
         });
       }, function (error) {
-
         // propagating the error message, couldn't fetch cubes
         AppDispatcher.dispatch({
           actionType: AdhocQueryConstants.RECEIVE_TABLES_FAILED,
@@ -207,6 +339,27 @@ let AdhocQueryActions = {
   cancelQuery (secretToken, handle) {
     AdhocQueryAdapter.cancelQuery(secretToken, handle);
     // TODO finish this up
+  },
+
+  runSavedQuery (secretToken, id, params) {
+    AdhocQueryAdapter.runSavedQuery(secretToken, id, params)
+      .then(handle => {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE,
+          payload: { queryHandle: handle }
+        });
+      }, (error) => {
+        // error response contains an error XML with code, message and
+        // stacktrace
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
+          payload: {
+            type: 'Error',
+            text: error.getElementsByTagName('code')[0].textContent + ': ' +
+              error.getElementsByTagName('message')[0].textContent
+          }
+        });
+      });
   }
 };
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/adapters/AdhocQueryAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/AdhocQueryAdapter.js b/lens-ui/app/adapters/AdhocQueryAdapter.js
index 98f9b49..24e72ef 100644
--- a/lens-ui/app/adapters/AdhocQueryAdapter.js
+++ b/lens-ui/app/adapters/AdhocQueryAdapter.js
@@ -24,10 +24,14 @@ import Config from 'config.json';
 
 let baseUrl = Config.baseURL;
 let urls = {
-  'getDatabases': 'metastore/databases',
-  'getCubes': 'metastore/cubes',
-  'query': 'queryapi/queries', // POST on this to execute, GET to fetch all
-  'getTables': 'metastore/nativetables'
+  getDatabases: 'metastore/databases',
+  getCubes: 'metastore/cubes',
+  query: 'queryapi/queries', // POST on this to execute, GET to fetch all
+  getTables: 'metastore/nativetables',
+  getSavedQueries: 'queryapi/savedqueries',
+  parameters: 'queryapi/savedqueries/parameters',
+  saveQuery: 'queryapi/savedqueries', // POST to save, PUT to update, {id} for GET
+  runSavedQuery: 'queryapi/savedqueries'
 };
 
 let AdhocQueryAdapter = {
@@ -54,13 +58,39 @@ let AdhocQueryAdapter = {
     formData.append('query', query);
     formData.append('operation', 'execute');
 
-    if (queryName)  formData.append('queryName', queryName);
+    if (queryName) formData.append('queryName', queryName);
 
     return BaseAdapter.post(url, formData, {
       contentType: 'multipart/form-data'
     });
   },
 
+  saveQuery (secretToken, user, query, options) {
+    let url = baseUrl + urls.saveQuery;
+    let queryToBeSaved = {
+      owner: user,
+      name: options.name || '',
+      query: query,
+      description: options.description || '',
+      parameters: options.parameters || []
+    };
+
+    return BaseAdapter.post(url, queryToBeSaved);
+  },
+
+  updateSavedQuery (secretToken, user, query, options, id) {
+    let url = baseUrl + urls.saveQuery + '/' + id;
+    let queryToBeSaved = {
+      owner: user,
+      name: options.name || '',
+      query: query,
+      description: options.description || '',
+      parameters: options.parameters || []
+    };
+
+    return BaseAdapter.put(url, queryToBeSaved);
+  },
+
   getQuery (secretToken, handle) {
     let url = baseUrl + urls.query + '/' + handle;
     return BaseAdapter.get(url, {sessionid: secretToken});
@@ -79,9 +109,8 @@ let AdhocQueryAdapter = {
 
     return BaseAdapter.get(url, queryOptions)
       .then(function (queryHandles) {
-
         // FIXME limiting to 10 for now
-        //let handles = queryHandles.slice(0, 10);
+        // let handles = queryHandles.slice(0, 10);
         return Promise.all(queryHandles.map((handle) => {
           return BaseAdapter.get(url + '/' + handle.handleId, {
             sessionid: secretToken,
@@ -92,13 +121,12 @@ let AdhocQueryAdapter = {
   },
 
   getQueryResult (secretToken, handle, queryMode) {
-
     // on page refresh, the store won't have queryMode so fetch query
     // this is needed as we won't know in which mode the query was fired
     if (!queryMode) {
       this.getQuery(secretToken, handle).then((query) => {
         queryMode = query.isPersistent;
-        queryMode = queryMode ? 'PERSISTENT': 'INMEMORY';
+        queryMode = queryMode ? 'PERSISTENT' : 'INMEMORY';
         return this._inMemoryOrPersistent(secretToken, handle, queryMode);
       });
     } else {
@@ -106,8 +134,6 @@ let AdhocQueryAdapter = {
     }
   },
 
-  // a method used only internally to figure out
-  // whether to fetch INMEMORY or PERSISTENT results
   _inMemoryOrPersistent (secretToken, handle, queryMode) {
     return queryMode === 'PERSISTENT' ?
       this.getDownloadURL(secretToken, handle) :
@@ -139,6 +165,11 @@ let AdhocQueryAdapter = {
     return Promise.resolve(downloadURL);
   },
 
+  getSavedQueryById (secretToken, id) {
+    let url = baseUrl + urls.saveQuery + '/' + id;
+    return BaseAdapter.get(url, {sessionid: secretToken});
+  },
+
   getInMemoryResults (secretToken, handle) {
     let resultUrl = baseUrl + urls.query + '/' + handle + '/resultset';
     let results = BaseAdapter.get(resultUrl, {
@@ -151,6 +182,33 @@ let AdhocQueryAdapter = {
     });
 
     return Promise.all([results, meta]);
+  },
+
+  getSavedQueries (secretToken, user, options = {}) {
+    let url = baseUrl + urls.getSavedQueries;
+    return BaseAdapter.get(url, {
+      user: user,
+      sessionid: secretToken,
+      start: options.offset || 0,
+      count: options.pageSize || 10
+    });
+  },
+
+  getParams (secretToken, query) {
+    let url = baseUrl + urls.parameters;
+    return BaseAdapter.get(url, {query: query});
+  },
+
+  runSavedQuery (secretToken, id, params) {
+    let queryParamString = BaseAdapter.jsonToQueryParams(params);
+    let url = baseUrl + urls.runSavedQuery + '/' + id + queryParamString;
+
+    let formData = new FormData();
+    formData.append('sessionid', secretToken);
+
+    return BaseAdapter.post(url, formData, {
+      contentType: 'multipart/form-data'
+    });
   }
 };
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/adapters/BaseAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/BaseAdapter.js b/lens-ui/app/adapters/BaseAdapter.js
index 81b9ddc..b22eefc 100644
--- a/lens-ui/app/adapters/BaseAdapter.js
+++ b/lens-ui/app/adapters/BaseAdapter.js
@@ -17,74 +17,69 @@
 * under the License.
 */
 
-import reqwest from 'reqwest';
+import reqwest from 'qwest';
 import Promise from 'bluebird';
 
 import Config from 'config.json';
+import XMLAdapter from './XMLAdapter';
 
 function makeReqwest (url, method, data, options = {}) {
-  let reqwestOptions = {
-    url: url,
-    method: method,
-    contentType: 'application/json',
-    type: 'json',
-    headers: {}
-  };
-
+  let reqwestOptions = { headers: {}, timeout: 200000 }; // a large enough for native tables
   if (Config.headers) reqwestOptions.headers = Config.headers;
+  reqwestOptions.responseType = !options.contentType ? 'json' : 'document';
 
-  // delete Content-Type and add Accept
-  reqwestOptions.headers['Accept'] = 'application/json';
-  delete reqwestOptions.headers['Content-Type'];
-  if (data) reqwestOptions.data = data;
-  if (options.contentType === 'multipart/form-data') {
-    reqwestOptions.processData = false;
-    reqwestOptions.contentType = 'multipart/form-data';
-
-    // because server can't handle JSON response on POST
-    delete reqwestOptions.type;
-    delete reqwestOptions.headers['Accept'];
+  if (reqwestOptions.responseType !== 'document') {
+    if (method === 'post' || method === 'put') reqwestOptions.dataType = 'json';
+  } else {
+    delete reqwestOptions.headers['Content-Type'];
   }
 
-  return new Promise ((resolve, reject) => {
-    reqwest(reqwestOptions)
-      .then ((response) => {
+  return new Promise((resolve, reject) => {
+    reqwest[method](url, data, reqwestOptions)
+      .then((response) => {
+        response = reqwestOptions.responseType === 'json' ?
+          response.response :
+          XMLAdapter.stringToXML(response.response);
+
         resolve(response);
       }, (error) => {
-        reject(error);
-      });
+        let response = error.responseType !== 'json' ?
+          XMLAdapter.stringToXML(error.response) :
+          error.response;
+        reject(response);
+      }).catch(e => console.error(e));
   });
 }
 
-function deleteRequest (url, dataArray) {
-  return makeReqwest(url, 'delete', dataArray);
-}
-
-function get (url, dataArray, options) {
-  return makeReqwest(url, 'get', dataArray, options);
-}
-
-// TODO need to fix this unused 'options'. What params can it have?
-function postJson (url, data, options = {}) {
-  return makeReqwest(url, 'post', data, {contentType: 'application/json'});
-}
-
-function postFormData (url, data, options = {}) {
-  return makeReqwest(url, 'post', data, options);
-}
-
 let BaseAdapter = {
-  get: get,
+  get (url, data, options) {
+    return makeReqwest(url, 'get', data, options);
+  },
 
   post (url, data, options = {}) {
-    if (options.contentType) {
-      return postFormData(url, data, options);
-    } else {
-      return postJson(url, data, options);
-    }
+    return makeReqwest(url, 'post', data, options);
+  },
+
+  put (url, data, options = {}) {
+    return makeReqwest(url, 'put', data, options);
   },
 
-  delete: deleteRequest
+  delete (url, data) {
+    return makeReqwest(url, 'delete', data);
+  },
+
+  jsonToQueryParams (json) {
+    // if json is an array?
+    var queryParams = '?';
+    if (!Object.prototype.toString.call(json).match('Array')) json = [json];
+
+    json.forEach(object => {
+      Object.keys(object).forEach(key => {
+        queryParams += key + '=' + object[key] + '&';
+      });
+    });
+    return queryParams.slice(0, -1);
+  }
 };
 
 export default BaseAdapter;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/adapters/XMLAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/XMLAdapter.js b/lens-ui/app/adapters/XMLAdapter.js
new file mode 100644
index 0000000..a206a1e
--- /dev/null
+++ b/lens-ui/app/adapters/XMLAdapter.js
@@ -0,0 +1,37 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+// converts string to XML and vice-versa
+// http://stackoverflow.com/questions/3054108/how-to-convert-string-to-xml-object-in-javascript
+
+let XMLAdapter = {
+  stringToXML (string) {
+    if (window.DOMParser) {
+      return new DOMParser().parseFromString(string, 'text/xml');
+    }
+
+    // IE?
+    var xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
+    xmlDoc.async = 'false';
+    xmlDoc.loadXML(string);
+    return xmlDoc;
+  }
+};
+
+export default XMLAdapter;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/app.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/app.js b/lens-ui/app/app.js
index 3e389a7..73cb511 100644
--- a/lens-ui/app/app.js
+++ b/lens-ui/app/app.js
@@ -19,32 +19,36 @@
 
 import React from 'react';
 import Router from 'react-router';
-import { DefaultRoute, Route, RouteHandler } from 'react-router';
+import { DefaultRoute, Route } from 'react-router';
 
+import './styles/less/globals.less';
+import './styles/css/global.css';
+
+import Login from './components/LoginComponent';
+import Logout from './components/LogoutComponent';
 import About from './components/AboutComponent';
 import App from './components/AppComponent';
 import AdhocQuery from './components/AdhocQueryComponent';
-import Login from './components/LoginComponent';
-import Logout from './components/LogoutComponent';
 import QueryResults from './components/QueryResultsComponent';
 import CubeSchema from './components/CubeSchemaComponent';
 import QueryDetailResult from './components/QueryDetailResultComponent';
 import TableSchema from './components/TableSchemaComponent';
-import LoginActions from './actions/LoginActions';
+import SavedQueries from './components/SavedQueriesComponent';
 
 let routes = (
-  <Route name="app" path="/" handler={App} >
-    <Route name="login" handler={Login}/>
-    <Route name="logout" handler={Logout}/>
-    <Route name="query" path="query" handler={AdhocQuery} >
-      <Route name="results" handler={QueryResults}/>
-      <Route name="result" path="/results/:handle" handler={QueryDetailResult}/>
-      <Route name="cubeschema" path="schema/cube/:cubeName" handler={CubeSchema}/>
-      <Route name="tableschema" path="schema/table/:tableName"
+  <Route name='app' path='/' handler={App} >
+    <Route name='login' handler={Login}/>
+    <Route name='logout' handler={Logout}/>
+    <Route name='query' path='query' handler={AdhocQuery} >
+      <Route name='results' handler={QueryResults}/>
+      <Route name='savedqueries' handler={SavedQueries}/>
+      <Route name='result' path='/results/:handle' handler={QueryDetailResult}/>
+      <Route name='cubeschema' path='schema/cube/:cubeName' handler={CubeSchema}/>
+      <Route name='tableschema' path='schema/table/:tableName'
         handler={TableSchema}/>
 
     </Route>
-    <Route name="about" handler={About} />
+    <Route name='about' handler={About} />
     <DefaultRoute handler={AdhocQuery} />
   </Route>
 );

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/AdhocQueryComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AdhocQueryComponent.js b/lens-ui/app/components/AdhocQueryComponent.js
index 66ddf75..32fab33 100644
--- a/lens-ui/app/components/AdhocQueryComponent.js
+++ b/lens-ui/app/components/AdhocQueryComponent.js
@@ -25,50 +25,22 @@ import Sidebar from './SidebarComponent';
 import RequireAuthentication from './RequireAuthenticationComponent';
 
 class AdhocQuery extends React.Component {
-  constructor (props) {
-    super(props);
-    this.state = {toggleQueryBox: true}; // show box when true, hide on false
-    this.toggleQueryBox = this.toggleQueryBox.bind(this);
-  }
-
-  render() {
-    let toggleButtonClass = this.state.toggleQueryBox ? 'default' : 'primary';
-
+  render () {
     return (
-      <section className="row">
-        <div className="col-md-4">
+      <section className='row'>
+        <div className='col-md-4'>
           <Sidebar />
         </div>
 
-        <div className="col-md-8">
-          <div className="panel panel-default">
-            <div className="panel-heading">
-              <h3 className="panel-title">
-                Compose
-                <button
-                  className={'btn btn-xs pull-right btn-' + toggleButtonClass}
-                  onClick={this.toggleQueryBox}>
-                  {this.state.toggleQueryBox ? 'Hide': 'Show'} Query Box
-                </button>
-              </h3>
-            </div>
-            <div className="panel-body" style={{padding: '0px'}}>
-              <QueryBox toggleQueryBox={this.state.toggleQueryBox} {...this.props}/>
-            </div>
-          </div>
+        <div className='col-md-8'>
+          <QueryBox {...this.props}/>
 
-          <RouteHandler toggleQueryBox={this.state.toggleQueryBox}/>
+          <RouteHandler/>
         </div>
       </section>
     );
   }
-
-  // FIXME persist the state in the URL as well
-  toggleQueryBox () {
-    this.setState({toggleQueryBox: !this.state.toggleQueryBox});
-  }
-};
+}
 
 let AuthenticatedAdhocQuery = RequireAuthentication(AdhocQuery);
-
 export default AuthenticatedAdhocQuery;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/AppComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AppComponent.js b/lens-ui/app/components/AppComponent.js
index d7a38f9..216eed4 100644
--- a/lens-ui/app/components/AppComponent.js
+++ b/lens-ui/app/components/AppComponent.js
@@ -22,14 +22,13 @@ import { RouteHandler } from 'react-router';
 
 import Header from './HeaderComponent';
 
-export default class AppComponent extends React.Component {
-
-  render() {
+export default class App extends React.Component {
+  render () {
     return (
       <section>
         <Header />
 
-        <div className="container-fluid">
+        <div className='container-fluid'>
           <RouteHandler />
         </div>
       </section>
@@ -37,4 +36,4 @@ export default class AppComponent extends React.Component {
   }
 }
 
-export default AppComponent;
+export default App;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/CubeSchemaComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeSchemaComponent.js b/lens-ui/app/components/CubeSchemaComponent.js
index 593c54a..c56cb15 100644
--- a/lens-ui/app/components/CubeSchemaComponent.js
+++ b/lens-ui/app/components/CubeSchemaComponent.js
@@ -41,9 +41,9 @@ function constructMeasureTable (cubeName, measures) {
   });
 
   return (
-    <div class="table-responsive">
-      <table className="table table-striped table-condensed">
-        <caption className="bg-primary text-center">Measures</caption>
+    <div className='table-responsive'>
+      <table className='table table-striped table-condensed'>
+        <caption className='bg-primary text-center'>Measures</caption>
         <thead>
           <tr>
             <th>Name</th>
@@ -76,9 +76,9 @@ function constructDimensionTable (cubeName, dimensions) {
   });
 
   return (
-    <div class="table-responsive">
-      <table className="table table-striped">
-        <caption className="bg-primary text-center">Dimensions</caption>
+    <div className='table-responsive'>
+      <table className='table table-striped'>
+        <caption className='bg-primary text-center'>Dimensions</caption>
         <thead>
           <tr>
             <th>Name</th>
@@ -119,6 +119,7 @@ class CubeSchema extends React.Component {
   }
 
   componentWillReceiveProps (props) {
+    // TODO are props updated automatically, unlike state?
     let cubeName = props.params.cubeName;
     let cube = getCubes()[cubeName];
 
@@ -132,7 +133,6 @@ class CubeSchema extends React.Component {
 
     // empty the previous state
     this.setState({ cube: {} });
-
   }
 
   render () {
@@ -140,21 +140,17 @@ class CubeSchema extends React.Component {
 
     // this will be empty if it's the first time so show a loader
     if (!this.state.cube.isLoaded) {
-      schemaSection = <Loader size="8px" margin="2px" />;
+      schemaSection = <Loader size='8px' margin='2px' />;
     } else {
-
       // if we have cube state
       let cube = this.state.cube;
       if (this.props.query.type === 'measures') {
-
         // show only measures
         schemaSection = constructMeasureTable(cube.name, cube.measures);
       } else if (this.props.query.type === 'dimensions') {
-
         // show only dimensions
         schemaSection = constructDimensionTable(cube.name, cube.dimensions);
       } else {
-
         // show both measures, dimensions
         schemaSection = (
           <div>
@@ -170,16 +166,15 @@ class CubeSchema extends React.Component {
     return (
 
       <section>
-        <div className="panel panel-default">
-          <div className="panel-heading">
-            <h3 className="panel-title">Schema Details: &nbsp;
-              <strong className="text-primary">
+        <div className='panel panel-default'>
+          <div className='panel-heading'>
+            <h3 className='panel-title'>Schema Details: &nbsp;
+              <strong className='text-primary'>
                  {this.props.params.cubeName}
               </strong>
             </h3>
           </div>
-          <div className="panel-body" style={{overflowY: 'auto',
-            maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+          <div className='panel-body'>
             {schemaSection}
           </div>
         </div>
@@ -193,4 +188,9 @@ class CubeSchema extends React.Component {
   }
 }
 
+CubeSchema.propTypes = {
+  query: React.PropTypes.object,
+  params: React.PropTypes.object
+};
+
 export default CubeSchema;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/CubeTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeTreeComponent.js b/lens-ui/app/components/CubeTreeComponent.js
index 241c12f..e348898 100644
--- a/lens-ui/app/components/CubeTreeComponent.js
+++ b/lens-ui/app/components/CubeTreeComponent.js
@@ -18,7 +18,6 @@
 */
 
 import React from 'react';
-import Alert from 'react-bootstrap';
 import TreeView from 'react-treeview';
 import assign from 'object-assign';
 import { Link } from 'react-router';
@@ -66,8 +65,7 @@ class CubeTree extends React.Component {
     CubeStore.removeChangeListener(this._onChange);
   }
 
-  render() {
-
+  render () {
     // cube tree structure sample
     // [{
     //   name: 'Cube-1',
@@ -79,50 +77,56 @@ class CubeTree extends React.Component {
     var cubeTree = Object.keys(this.state.cubes).map((cubeName, i) => {
       let cube = cubeHash[cubeName];
 
-      let label = <Link to="cubeschema" params={{cubeName: cubeName}}>
-          <span className="node">{cube.name}</span>
+      let label = <Link to='cubeschema' params={{cubeName: cubeName}}>
+          <span className='node'>{cube.name}</span>
         </Link>;
 
-      let measureLabel = <Link to="cubeschema" params={{cubeName: cubeName}}
+      let measureLabel = <Link to='cubeschema' params={{cubeName: cubeName}}
         query={{type: 'measures'}}>
-          <span className="quiet">Measures</span>
+          <span className='quiet'>Measures</span>
         </Link>;
 
-      let dimensionLabel = <Link to="cubeschema" params={{cubeName: cubeName}}
+      let dimensionLabel = <Link to='cubeschema' params={{cubeName: cubeName}}
         query={{type: 'dimensions'}}>
-          <span className="quiet">Dimensions</span>
-        </Link>
+          <span className='quiet'>Dimensions</span>
+        </Link>;
       return (
         <TreeView key={cube.name + '|' + i} nodeLabel={label}
-          defaultCollapsed={true} onClick={this.getDetails.bind(this, cube.name)}>
+          defaultCollapsed={!cube.isLoaded} onClick={this.getDetails.bind(this, cube.name)}>
 
           <TreeView key={cube.name + '|measures'} nodeLabel={measureLabel}
             defaultCollapsed={!cube.isLoaded}>
             { cube.measures ? cube.measures.map(measure => {
               return (
-                <div key={measure.name} className="treeNode measureNode">
+                <div key={measure.name} className='treeNode measureNode'>
                   {measure.name} ({measure.default_aggr})
                 </div>
               );
-            }): null }
+            }) : null }
           </TreeView >
 
           <TreeView key={cube.name + '|dimensions'} nodeLabel={dimensionLabel}
             defaultCollapsed={!cube.isLoaded}>
             { cube.dimensions ? cube.dimensions.map(dimension => {
               return (
-                <div className="treeNode dimensionNode" key={dimension.name}>
+                <div className='treeNode dimensionNode' key={dimension.name}>
                   {dimension.name}
                 </div>
               );
-            }): null }
+            }) : null }
           </TreeView >
 
         </TreeView >
       );
     });
 
-    if (this.state.loading) cubeTree = <Loader size="4px" margin="2px"/>;
+    if (this.state.loading) {
+      cubeTree = <Loader size='4px' margin='2px'/>;
+    } else if (!this.state.cubes.length) {
+      cubeTree = (<div className='alert-danger' style={{padding: '8px 5px'}}>
+          <strong>Sorry, we couldn&#39;t find any cubes.</strong>
+        </div>);
+    }
 
     let collapseClass = ClassNames({
       'pull-right': true,
@@ -137,9 +141,9 @@ class CubeTree extends React.Component {
     });
 
     return (
-      <div className="panel panel-default">
-        <div className="panel-heading">
-          <h3 className="panel-title">
+      <div className='panel panel-default'>
+        <div className='panel-heading'>
+          <h3 className='panel-title'>
             Cubes
             <span className={collapseClass} onClick={this.toggle}></span>
           </h3>

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/DatabaseComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/DatabaseComponent.js b/lens-ui/app/components/DatabaseComponent.js
index 09ee2eb..09c9e7b 100644
--- a/lens-ui/app/components/DatabaseComponent.js
+++ b/lens-ui/app/components/DatabaseComponent.js
@@ -70,28 +70,28 @@ class DatabaseComponent extends React.Component {
     });
 
     databaseComponent = (<div>
-        <label className="control-label" id="db">Select a Database</label>
-        <select className="form-control" id="db" onChange={this.setDatabase}>
-          <option value="">Select</option>
+        <label className='control-label' id='db'>Select a Database</label>
+        <select className='form-control' id='db' onChange={this.setDatabase}>
+          <option value=''>Select</option>
           {this.state.databases.map(database => {
-            return <option value={database}>{database}</option>;
+            return <option key={database} value={database}>{database}</option>;
           })}
         </select>
       </div>);
 
     if (this.state.loading) {
-      databaseComponent = <Loader size="4px" margin="2px"></Loader>;
+      databaseComponent = <Loader size='4px' margin='2px' />;
     } else if (!this.state.databases.length) {
-      databaseComponent = (<div className="alert-danger"
+      databaseComponent = (<div className='alert-danger'
           style={{padding: '8px 5px'}}>
           <strong>Sorry, we couldn&#39;t find any databases.</strong>
         </div>);
     }
 
     return (
-      <div className="panel panel-default">
-        <div className="panel-heading">
-          <h3 className="panel-title">
+      <div className='panel panel-default'>
+        <div className='panel-heading'>
+          <h3 className='panel-title'>
             Tables
             <span className={collapseClass} onClick={this.toggle}></span>
           </h3>

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/HeaderComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/HeaderComponent.js b/lens-ui/app/components/HeaderComponent.js
index 5ec3397..4f8d0f1 100644
--- a/lens-ui/app/components/HeaderComponent.js
+++ b/lens-ui/app/components/HeaderComponent.js
@@ -18,12 +18,9 @@
 */
 
 import React from 'react';
-import Router from 'react-router';
 import { Link } from 'react-router';
 
-import Logout from './LogoutComponent';
 import UserStore from '../stores/UserStore';
-import Config from 'config.json';
 
 class Header extends React.Component {
   constructor () {
@@ -47,29 +44,29 @@ class Header extends React.Component {
 
   render () {
     return (
-      <nav className="navbar navbar-inverse navbar-static-top">
-        <div className="container">
-          <div className="navbar-header">
-            <button type="button" className="navbar-toggle collapsed"
-                data-toggle="collapse" data-target="#navbar"
-                aria-expanded="false" aria-controls="navbar">
-              <span className="sr-only">Toggle navigation</span>
-              <span className="icon-bar"></span>
-              <span className="icon-bar"></span>
-              <span className="icon-bar"></span>
+      <nav className='navbar navbar-inverse navbar-static-top'>
+        <div className='container'>
+          <div className='navbar-header'>
+            <button type='button' className='navbar-toggle collapsed'
+                data-toggle='collapse' data-target='#navbar'
+                aria-expanded='false' aria-controls='navbar'>
+              <span className='sr-only'>Toggle navigation</span>
+              <span className='icon-bar'></span>
+              <span className='icon-bar'></span>
+              <span className='icon-bar'></span>
             </button>
-            <Link className="navbar-brand" to="app">LENS Query<sup>&beta;</sup></Link>
+            <Link className='navbar-brand' to='app'>LENS Query<sup>&beta;</sup></Link>
           </div>
-          <div id="navbar" className="collapse navbar-collapse">
-            <ul className="nav navbar-nav">
-              <li><Link to="about">About</Link></li>
+          <div id='navbar' className='collapse navbar-collapse'>
+            <ul className='nav navbar-nav'>
+              <li><Link to='about'>About</Link></li>
             </ul>
 
             { this.state.userName &&
-              (<ul className="nav navbar-nav navbar-right">
+              (<ul className='nav navbar-nav navbar-right'>
                 <li>
-                  <Link to="logout" className="glyphicon glyphicon-log-out"
-                    title="Logout">
+                  <Link to='logout' className='glyphicon glyphicon-log-out'
+                    title='Logout'>
                     <span> {this.state.userName}</span>
                   </Link>
                 </li>

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/LoaderComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LoaderComponent.js b/lens-ui/app/components/LoaderComponent.js
index ba11c64..72b8f45 100644
--- a/lens-ui/app/components/LoaderComponent.js
+++ b/lens-ui/app/components/LoaderComponent.js
@@ -25,7 +25,7 @@ class Loader extends React.Component {
   render () {
     return (
       <section style={{margin: '0 auto', maxWidth: '12%'}}>
-        <GridLoader {...this.props} color="#337ab7"/>
+        <GridLoader {...this.props} color='#337ab7'/>
       </section>
     );
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/LoginComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LoginComponent.js b/lens-ui/app/components/LoginComponent.js
index cf95af9..c0840e1 100644
--- a/lens-ui/app/components/LoginComponent.js
+++ b/lens-ui/app/components/LoginComponent.js
@@ -53,19 +53,19 @@ class Login extends React.Component {
 
   render () {
     return (
-      <section class="row" style={{margin: 'auto'}}>
-        <form className="form-signin" onSubmit={this.handleSubmit}>
-          <h2 className="form-signin-heading">Sign in</h2>
-          <label for="inputEmail" className="sr-only">Email address</label>
-          <input ref="email" id="inputEmail" className="form-control"
-            placeholder="Email address" required autofocus/>
-          <label for="inputPassword" className="sr-only">Password</label>
-          <input ref="pass" type="password" id="inputPassword"
-            className="form-control" placeholder="Password" required/>
-          <button className="btn btn-primary btn-block"
-            type="submit">Sign in</button>
+      <section className='row' style={{margin: 'auto'}}>
+        <form className='form-signin' onSubmit={this.handleSubmit}>
+          <h2 className='form-signin-heading'>Sign in</h2>
+          <label htmlFor='inputEmail' className='sr-only'>Email address</label>
+          <input ref='email' id='inputEmail' className='form-control'
+            placeholder='Email address' required autoFocus/>
+          <label htmlFor='inputPassword' className='sr-only'>Password</label>
+          <input ref='pass' type='password' id='inputPassword'
+            className='form-control' placeholder='Password' required/>
+          <button className='btn btn-primary btn-block'
+            type='submit'>Sign in</button>
           {this.state.error && (
-            <div className="alert-danger text-center"
+            <div className='alert-danger text-center'
               style={{marginTop: '5px', padding: '0px 3px'}}>
               <h5>Sorry, authentication failed.</h5>
               <small>{this.state.errorMessage}</small>

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/LogoutComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LogoutComponent.js b/lens-ui/app/components/LogoutComponent.js
index 3fc1627..9680a76 100644
--- a/lens-ui/app/components/LogoutComponent.js
+++ b/lens-ui/app/components/LogoutComponent.js
@@ -19,7 +19,6 @@
 
 import React from 'react';
 import { Link } from 'react-router';
-import Config from 'config.json';
 
 import UserStore from '../stores/UserStore';
 
@@ -31,9 +30,9 @@ class Logout extends React.Component {
 
   render () {
     return (
-      <div className="jumbotron text-center">
+      <div className='jumbotron text-center'>
         <h3>You&#39;ve succesfully logged out.</h3>
-        <p><Link to="/">Login</Link> to use this awesome app!</p>
+        <p><Link to='/'>Login</Link> to use this awesome app!</p>
       </div>
     );
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryBoxComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryBoxComponent.js b/lens-ui/app/components/QueryBoxComponent.js
index 6d5843c..6f4eeb7 100644
--- a/lens-ui/app/components/QueryBoxComponent.js
+++ b/lens-ui/app/components/QueryBoxComponent.js
@@ -18,7 +18,9 @@
 */
 
 import React from 'react';
+import ClassNames from 'classnames';
 import CodeMirror from 'codemirror';
+import assign from 'object-assign';
 import 'codemirror/lib/codemirror.css';
 import 'codemirror/addon/edit/matchbrackets.js';
 import 'codemirror/addon/hint/sql-hint.js';
@@ -32,12 +34,23 @@ import AdhocQueryStore from '../stores/AdhocQueryStore';
 import CubeStore from '../stores/CubeStore';
 import TableStore from '../stores/TableStore';
 import DatabaseStore from '../stores/DatabaseStore';
+import SavedQueryStore from '../stores/SavedQueryStore';
+import QueryParams from './QueryParamsComponent';
 import Config from 'config.json';
 import '../styles/css/query-component.css';
 
 // keeping a handle to CodeMirror instance,
 // to be used to retrieve the contents of the editor
 let codeMirror = null;
+let codeMirrorHints = {};
+
+// list of possible client messages
+let clientMessages = {
+  runQuery: 'Running your query...',
+  saveQuery: 'Saving your query...',
+  noName: 'Name is mandatory for a saved query.',
+  updateQuery: 'Updating saved query...'
+};
 
 function setLimit (query) {
   // since pagination is not enabled on server, limit the query to 1000
@@ -45,8 +58,7 @@ function setLimit (query) {
   // dumb way, checking only last two words for `limit <number>` pattern
   let temp = query.split(' ');
   if (temp.slice(-2)[0].toLowerCase() === 'limit') {
-
-    if (temp.slice(-1)[0] > 1000)  temp.splice(-1, 1, 1000);
+    if (temp.slice(-1)[0] > 1000) temp.splice(-1, 1, 1000);
     query = temp.join(' ');
   } else {
     query += ' limit 1000';
@@ -66,169 +78,214 @@ function setCode (code) {
 // TODO improve this.
 // this takes in the query handle and writes the query
 // used from Edit Query link
-function fetchQuery (props) {
-  if (props.query && props.query.handle) {
-    let query = AdhocQueryStore.getQueries()[props.query.handle];
+function fetchQueryForEdit (props) {
+  let query = AdhocQueryStore.getQueries()[props.query.handle];
 
-    if (query) {
-      setCode(query.userQuery);
-    }
+  if (query) {
+    setCode(query.userQuery);
   }
 }
 
 function setupCodeMirror (domNode) {
-
   // instantiating CodeMirror intance with some properties.
   codeMirror = CodeMirror.fromTextArea(domNode, {
     mode: 'text/x-sql',
     indentWithTabs: true,
     smartIndent: true,
     lineNumbers: true,
-    matchBrackets : true,
+    matchBrackets: true,
     autofocus: true,
     lineWrapping: true
   });
 }
 
-function updateAutoComplete () {
-
-  // add autocomplete hints to the query box
-  let hints = {};
-
-  // cubes
-  let cubes = CubeStore.getCubes(); // hashmap
-  Object.keys(cubes).forEach((cubeName) => {
-    let cube = cubes[cubeName];
-    hints[cubeName] = [];
-
-    if (cube.measures && cube.measures.length) {
-      cube.measures.forEach((measure) => {
-        hints[cubeName].push(measure.name);
-      });
-    }
-    if (cube.dimensions && cube.dimensions.length) {
-      cube.dimensions.forEach((dimension) => {
-        hints[cubeName].push(dimension.name);
-      });
-    }
-  });
-
-  //  tables
-  let databases = DatabaseStore.getDatabases() || [];
-  let tables = databases.map(db => {
-    if (TableStore.getTables(db)) {
-      return {
-        database: db,
-        tables: TableStore.getTables(db)
-      }
-    }
-  }).filter(item => { return !!item; }); // filtering undefined items
-
-  tables.forEach(tableObject => {
-    Object.keys(tableObject.tables).forEach(tableName => {
-      let table = tableObject.tables[tableName];
-      let qualifiedName = tableObject.database + '.' + tableName;
-      hints[qualifiedName] = [];
-      hints[tableName] = [];
-
-      if (table.columns && table.columns.length) {
-        table.columns.forEach((col) => {
-          hints[qualifiedName].push(col.name);
-          hints[tableName].push(col.name);
-          hints[col.name] = [];
-        });
-      }
-    });
-  });
-
-  codeMirror.options.hintOptions = { tables: hints };
-}
-
 class QueryBox extends React.Component {
   constructor (props) {
     super(props);
     this.runQuery = this.runQuery.bind(this);
+    this.saveQuery = this.saveQuery.bind(this);
     this._onChange = this._onChange.bind(this);
-
-    this.state = { querySubmitted: false, isRunQueryDisabled: true };
+    this.toggle = this.toggle.bind(this);
+    this.closeParamBox = this.closeParamBox.bind(this);
+    this.saveParams = this.saveParams.bind(this);
+    this._onChangeSavedQueryStore = this._onChangeSavedQueryStore.bind(this);
+    this._getSavedQueryDetails = this._getSavedQueryDetails.bind(this);
+    this.cancel = this.cancel.bind(this);
+    this.saveOrUpdate = this.saveOrUpdate.bind(this);
+    this.runSavedQuery = this.runSavedQuery.bind(this);
+
+    this.state = {
+      clientMessage: null, // to give user instant ack
+      isRunQueryDisabled: true,
+      serverMessage: null, // type (success or error), text as keys
+      isCollapsed: false,
+      params: null,
+      isModeEdit: false,
+      savedQueryId: null,
+      runImmediately: false
+    };
   }
 
   componentDidMount () {
-
     var editor = this.refs.queryEditor.getDOMNode();
     setupCodeMirror(editor);
 
     // disable 'Run Query' button when editor is empty
     // TODO: debounce this, as it'll happen on every key press. :(
     codeMirror.on('change', () => {
-      codeMirror.getValue() ?
-        this.state.isRunQueryDisabled = false :
-        this.state.isRunQueryDisabled = true;
+      this.state.isRunQueryDisabled = !codeMirror.getValue();
+      this.setState(this.state);
 
       this._onChange();
     });
 
     // to remove the previous query's submission notification
     codeMirror.on('focus', () => {
-      this.state.querySubmitted = false;
+      this.setState({ clientMessage: null });
     });
 
     // add Cmd + Enter to fire runQuery
-    codeMirror.setOption("extraKeys", {
-    'Cmd-Enter': (instance) => {
-      this.runQuery();
-    },
-    'Ctrl-Space': 'autocomplete'
-  });
+    codeMirror.setOption('extraKeys', {
+      'Cmd-Enter': instance => { this.runQuery(); },
+      'Ctrl-Space': 'autocomplete',
+      'Ctrl-S': instance => { this.saveQuery(); }
+    });
 
     AdhocQueryStore.addChangeListener(this._onChange);
-    CubeStore.addChangeListener(this._onChange);
-    TableStore.addChangeListener(this._onChange);
+    CubeStore.addChangeListener(this._onChangeCubeStore);
+    TableStore.addChangeListener(this._onChangeTableStore);
+    SavedQueryStore.addChangeListener(this._onChangeSavedQueryStore);
   }
 
   componentWillUnmount () {
-    AdhocQueryStore.addChangeListener(this._onChange);
-    CubeStore.addChangeListener(this._onChange);
-    TableStore.addChangeListener(this._onChange);
+    AdhocQueryStore.removeChangeListener(this._onChange);
+    CubeStore.removeChangeListener(this._onChangeCubeStore);
+    TableStore.removeChangeListener(this._onChangeTableStore);
+    SavedQueryStore.removeChangeListener(this._onChangeSavedQueryStore);
   }
 
   componentWillReceiveProps (props) {
-    fetchQuery(props);
+    // normal query
+    if (props.query && props.query.handle) {
+      fetchQueryForEdit(props);
+      // clear saved query state
+      this.setState({
+        params: null,
+        savedQueryId: null,
+        isModeEdit: false
+      });
+    // saved query
+    } else if (props.query && props.query.savedquery) {
+      let queryId = props.query.savedquery;
+      let savedQuery = SavedQueryStore.getSavedQueries()[queryId];
+      if (savedQuery) {
+        setCode(savedQuery.query);
+        this.refs.queryName.getDOMNode().value = savedQuery.name;
+        this.setState({
+          params: savedQuery.parameters,
+          savedQueryId: savedQuery.id,
+          isModeEdit: true
+        });
+      }
+    }
   }
 
   render () {
-    let queryBoxClass = this.props.toggleQueryBox ? '': 'hide';
+    let collapseClass = ClassNames({
+      'pull-right': true,
+      'glyphicon': true,
+      'glyphicon-chevron-up': !this.state.isCollapsed,
+      'glyphicon-chevron-down': this.state.isCollapsed
+    });
+
+    let panelBodyClassName = ClassNames({
+      'panel-body': true,
+      'hide': this.state.isCollapsed
+    });
+
+    let notificationClass = ClassNames({
+      'alert': true,
+      'alert-danger': this.state.serverMessage && this.state.serverMessage.type === 'Error',
+      'alert-success': this.state.serverMessage && this.state.serverMessage.type !== 'Error'
+    });
 
     return (
-      <section className={queryBoxClass}>
-        <div style={{borderBottom: '1px solid #dddddd'}}>
-          <textarea ref="queryEditor"></textarea>
-        </div>
 
-        <div className="row" style={{padding: '6px 8px '}}>
-          <div className="col-lg-4 col-md-4 col-sm-4 col-xs-12">
-            <input type="text" className="form-control"
-              placeholder="Query Name (optional)" ref="queryName"/>
-          </div>
-          <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
-            {this.state.querySubmitted && (
-              <div className="alert alert-info" style={{padding: '5px 4px',
-                marginBottom: '0px'}}>
-                Query has been submitted. Results are on their way!
+      <div className='panel panel-default'>
+        <div className='panel-heading'>
+          <h3 className='panel-title'>
+            {this.state.isModeEdit ? 'Edit' : 'Compose'}
+            <span className={collapseClass} onClick={this.toggle}></span>
+          </h3>
+        </div>
+        <div className={panelBodyClassName} style={{padding: '0px'}}>
+          <section>
+            <div style={{borderBottom: '1px solid #dddddd'}}>
+              <textarea ref='queryEditor'></textarea>
+            </div>
+
+            <div className='row' style={{padding: '6px 8px '}}>
+              <div className='col-lg-4 col-md-4 col-sm-4 col-xs-12'>
+                <input type='text' className='form-control'
+                  placeholder='Query Name (optional)' ref='queryName'/>
+              </div>
+              <div className='col-lg-5 col-md-5 col-sm-5 col-xs-12'>
+                {this.state.clientMessage && (
+                  <div className='alert alert-info' style={{padding: '5px 4px',
+                    marginBottom: '0px'}}>
+                    {this.state.clientMessage}
+                  </div>
+                )}
+              </div>
+              <div className='col-lg-3 col-md-3 col-sm-3 col-xs-12'>
+                <button className='btn btn-default' style={{marginRight: '4px'}}
+                  onClick={this.saveOrUpdate} disabled={this.state.isRunQueryDisabled}
+                  title='Save'>
+                  <i className='fa fa-save fa-lg'></i>
+                </button>
+                <button className='btn btn-default' title='Run'
+                  onClick={this.runQuery} style={{marginRight: '4px'}}
+                  disabled={this.state.isRunQueryDisabled}>
+                  <i className='fa fa-play fa-lg'></i>
+                </button>
+                <button className='btn btn-default' onClick={this.cancel}
+                  title='Clear'>
+                  <i className='fa fa-ban fa-lg'></i>
+                </button>
+              </div>
+            </div>
+
+            { this.state.params && !!this.state.params.length &&
+              <QueryParams params={this.state.params} close={this.closeParamBox}
+                saveParams={this.saveParams}/>
+            }
+
+            { this.state.serverMessage &&
+              <div className={notificationClass} style={{marginBottom: '0px'}}>
+
+                {this.state.serverMessage.text}
+
+                { this.state.serverMessage.texts &&
+                  this.state.serverMessage.texts.map(e => {
+                    return (
+                      <li style={{listStyleType: 'none'}}>
+                        <strong>{e.code}</strong>: <span>{e.message}</span>
+                      </li>
+                    );
+                  })
+                }
               </div>
-            )}
-          </div>
-          <div className="col-lg-2 col-md-2 col-sm-2 col-xs-12">
-            <button className="btn btn-primary responsive"
-              onClick={this.runQuery} disabled={this.state.isRunQueryDisabled}>
-              Run Query
-            </button>
-          </div>
+            }
+          </section>
         </div>
-      </section>
+      </div>
     );
   }
 
+  saveOrUpdate () {
+    !this.state.isModeEdit ? this.saveQuery() : this.updateQuery();
+  }
+
   runQuery () {
     let queryName = this.refs.queryName.getDOMNode().value;
     let secretToken = UserStore.getUserDetails().secretToken;
@@ -237,14 +294,60 @@ class QueryBox extends React.Component {
     // set limit if mode is in-memory
     if (!Config.isPersistent) query = setLimit(query);
 
-    AdhocQueryActions.executeQuery(secretToken, query, queryName);
+    AdhocQueryActions.runQuery(secretToken, query, queryName);
 
     // show user the query was posted successfully and empty the queryName
-    this.state.querySubmitted = true;
+    this.setState({ clientMessage: clientMessages.runQuery });
     this.refs.queryName.getDOMNode().value = '';
   }
 
-  _onChange () {
+  updateQuery (params) {
+    let query = this._getSavedQueryDetails(params);
+    if (!query) return;
+    AdhocQueryActions
+      .updateSavedQuery(query.secretToken, query.user, query.query, query.params, this.state.savedQueryId);
+    this.setState({ clientMessage: clientMessages.updateQuery });
+  }
+
+  saveQuery (params) {
+    let query = this._getSavedQueryDetails(params);
+    if (!query) return;
+    AdhocQueryActions
+      .saveQuery(query.secretToken, query.user, query.query, query.params);
+    this.setState({ clientMessage: clientMessages.saveQuery });
+  }
+
+  // internal which is called during save saved query & edit saved query
+  _getSavedQueryDetails (params) {
+    let queryName = this.refs.queryName.getDOMNode().value;
+    if (!queryName) {
+      this.setState({clientMessage: clientMessages.noName});
+      return;
+    }
+
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let user = UserStore.getUserDetails().email;
+    let query = codeMirror.getValue();
+
+    params = assign({}, params);
+    params.name = queryName;
+
+    return {
+      secretToken: secretToken,
+      user: user,
+      query: query,
+      params: params
+    };
+  }
+
+  _onChange (hash) { // can be error/success OR it can be saved query params
+    if (hash && hash.type) {
+      this.setState({serverMessage: hash, clientMessage: null});
+
+      if (hash.type === 'Error') return;
+    } else {
+      this.setState({serverMessage: null});
+    }
 
     // renders the detail result component if server
     // replied with a query handle.
@@ -252,27 +355,147 @@ class QueryBox extends React.Component {
     // clicked, and its action updates the store with query-handle.
     let handle = AdhocQueryStore.getQueryHandle();
     if (handle) {
-
-      // clear it else detail result component will be rendered
-      // every time the store emits a change event.
-      AdhocQueryStore.clearQueryHandle();
+      this.setState({ clientMessage: null });
 
       var { router } = this.context;
       router.transitionTo('result', {handle: handle});
     }
+  }
 
-    // TODO remove this.
-    // check if handle was passed as query param, and if that
-    // query was fetched and available in store now.
-    // if (this.props && this.props.query.handle) {
-    //
-    //   let query = AdhocQueryStore.getQueries()[this.props.query.handle];
-    //   if (query)  setCode(query.userQuery);
-    // }
+  _onChangeCubeStore () {
+    // cubes
+    let cubes = CubeStore.getCubes(); // hashmap
+    Object.keys(cubes).forEach((cubeName) => {
+      let cube = cubes[cubeName];
+      codeMirrorHints[cubeName] = [];
+
+      if (cube.measures && cube.measures.length) {
+        cube.measures.forEach((measure) => {
+          codeMirrorHints[cubeName].push(measure.name);
+        });
+      }
+      if (cube.dimensions && cube.dimensions.length) {
+        cube.dimensions.forEach((dimension) => {
+          codeMirrorHints[cubeName].push(dimension.name);
+        });
+      }
+    });
+
+    codeMirror.options.hintOptions = { tables: codeMirrorHints };
+  }
+
+  _onChangeTableStore () {
+    //  tables
+    let databases = DatabaseStore.getDatabases() || [];
+    let tables = databases.map(db => {
+      if (TableStore.getTables(db)) {
+        return {
+          database: db,
+          tables: TableStore.getTables(db)
+        };
+      }
+    }).filter(item => { return !!item; }); // filtering undefined items
+
+    tables.forEach(tableObject => {
+      Object.keys(tableObject.tables).forEach(tableName => {
+        let table = tableObject.tables[tableName];
+        let qualifiedName = tableObject.database + '.' + tableName;
+        codeMirrorHints[qualifiedName] = [];
+        codeMirrorHints[tableName] = [];
+
+        if (table.columns && table.columns.length) {
+          table.columns.forEach((col) => {
+            codeMirrorHints[qualifiedName].push(col.name);
+            codeMirrorHints[tableName].push(col.name);
+            codeMirrorHints[col.name] = [];
+          });
+        }
+      });
+    });
+
+    codeMirror.options.hintOptions = { tables: codeMirrorHints };
+  }
+
+  _onChangeSavedQueryStore (hash) {
+    if (!hash) return;
+
+    switch (hash.type) {
+      case 'failure':
+        this.state.clientMessage = null;
+        this.state.serverMessage = hash.message;
+        break;
+
+      case 'success':
+        this.state.clientMessage = null;
+        this.state.serverMessage = hash.message;
+        // make the mode of QueryBox back to normal, if it's in Edit
+        if (this.state.isModeEdit) {
+          this.state.isModeEdit = false;
+        }
+
+        // trigger to fetch the edited from server again
+        let token = UserStore.getUserDetails().secretToken;
+        if (hash.id) AdhocQueryActions.getSavedQueryById(token, hash.id);
+        // means the query was saved successfully.
+
+        // run immediately?
+        if (this.state.runImmediately && hash.id) {
+          this.runSavedQuery(hash.id);
+          this.state.runImmediately = false;
+        }
+
+        // make params null
+        this.state.params = null;
+
+        break;
+
+      case 'params':
+        this.state.params = hash.params;
+        break;
+    }
 
-    updateAutoComplete();
     this.setState(this.state);
   }
+
+  runSavedQuery (id) {
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let parameters = this.state.params.map(param => {
+      let object = {};
+      object[param.name] = param.defaultValue;
+      return object;
+    });
+    AdhocQueryActions.runSavedQuery(secretToken, id, parameters);
+  }
+
+  toggle () {
+    this.setState({isCollapsed: !this.state.isCollapsed});
+  }
+
+  closeParamBox () {
+    this.setState({params: null, clientMessage: null});
+  }
+
+  saveParams (params) { // contains parameters, description et all
+    this.state.params = assign(this.state.params, params.parameters);
+    this.state.runImmediately = params.runImmediately;
+
+    // edit or save new, only state variable will tell
+    !this.state.isModeEdit ? this.saveQuery(params) : this.updateQuery(params);
+  }
+
+  cancel () {
+    setCode('');
+    this.refs.queryName.getDOMNode().value = '';
+    this.setState({
+      clientMessage: null, // to give user instant ack
+      isRunQueryDisabled: true,
+      serverMessage: null, // type (success or error), text as keys
+      isCollapsed: false,
+      params: null,
+      isModeEdit: false,
+      savedQueryId: null
+    });
+  }
 }
 
 QueryBox.contextTypes = {

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryDetailResultComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryDetailResultComponent.js b/lens-ui/app/components/QueryDetailResultComponent.js
index b969a4a..096adde 100644
--- a/lens-ui/app/components/QueryDetailResultComponent.js
+++ b/lens-ui/app/components/QueryDetailResultComponent.js
@@ -19,7 +19,7 @@
 
 import React from 'react';
 
-import Loader from '../components/LoaderComponent';
+import Loader from './LoaderComponent';
 import AdhocQueryStore from '../stores/AdhocQueryStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
 import UserStore from '../stores/UserStore';
@@ -28,7 +28,6 @@ import QueryPreview from './QueryPreviewComponent';
 let interval = null;
 
 function isResultAvailableOnServer (handle) {
-
   // always check before polling
   let query = AdhocQueryStore.getQueries()[handle];
   if (query && query.status && query.status.status === 'SUCCESSFUL') {
@@ -38,9 +37,6 @@ function isResultAvailableOnServer (handle) {
 }
 
 function fetchResult (secretToken, handle) {
-
-  // this condition checks the query object, else
-  // we fetch it with the handle that we have
   if (isResultAvailableOnServer(handle)) {
     let query = AdhocQueryStore.getQueries()[handle];
     let mode = query.isPersistent ? 'PERSISTENT' : 'INMEMORY';
@@ -60,7 +56,7 @@ function constructTable (tableData) {
       return (<tr>{row.values.values.map(cell => {
         return <td>{(cell && cell.value) || <span style={{color: 'red'}}>NULL</span>}</td>;
       })}</tr>);
-  });
+    });
 
   // in case the results are empty, happens when LENS server has restarted
   // all in-memory results are wiped clean
@@ -73,8 +69,8 @@ function constructTable (tableData) {
   }
 
   return (
-    <div class="table-responsive">
-      <table className="table table-striped table-condensed">
+    <div className='table-responsive'>
+      <table className='table table-striped table-condensed'>
         <thead>
           <tr>{header}</tr>
         </thead>
@@ -118,9 +114,9 @@ class QueryDetailResult extends React.Component {
 
     // check if the query was persistent or in-memory
     if (query && query.isPersistent && query.status.status === 'SUCCESSFUL') {
-      result = (<div className="text-center">
+      result = (<div className='text-center'>
         <a href={queryResult.downloadURL} download>
-          <span className="glyphicon glyphicon-download-alt	"></span> Click
+          <span className='glyphicon glyphicon-download-alt	'></span> Click
           here to download the results as a CSV file
         </a>
       </div>);
@@ -128,16 +124,14 @@ class QueryDetailResult extends React.Component {
       result = constructTable(this.state.queryResult);
     }
 
-
-    if (this.state.loading) result = <Loader size="8px" margin="2px"></Loader>;
+    if (this.state.loading) result = <Loader size='8px' margin='2px' />;
 
     return (
-      <div className="panel panel-default">
-      <div className="panel-heading">
-        <h3 className="panel-title">Query Result</h3>
+      <div className='panel panel-default'>
+      <div className='panel-heading'>
+        <h3 className='panel-title'>Query Result</h3>
       </div>
-      <div className="panel-body" style={{overflowY: 'auto', padding: '0px',
-        maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+      <div className='panel-body no-padding'>
         <div>
           <QueryPreview key={query && query.queryHandle.handleId}
             {...query} />
@@ -149,7 +143,6 @@ class QueryDetailResult extends React.Component {
   }
 
   pollForResult (secretToken, handle) {
-
     // fetch results immediately if present, don't wait for 5 seconds
     // in setInterval below.
     // FIXME if I put a return in if construct, setInterval won't execute which
@@ -182,11 +175,15 @@ class QueryDetailResult extends React.Component {
       loading: loading,
       queryResult: result || {}, // result can be undefined so guarding it
       query: query
-    }
+    };
 
     this.setState(state);
-
   }
 }
 
+QueryDetailResult.propTypes = {
+  query: React.PropTypes.object,
+  params: React.PropTypes.object
+};
+
 export default QueryDetailResult;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryOperationsComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryOperationsComponent.js b/lens-ui/app/components/QueryOperationsComponent.js
index a17a636..e4cc1e7 100644
--- a/lens-ui/app/components/QueryOperationsComponent.js
+++ b/lens-ui/app/components/QueryOperationsComponent.js
@@ -46,9 +46,9 @@ class QueryOperations extends React.Component {
     });
 
     return (
-      <div className="panel panel-default">
-        <div className="panel-heading">
-          <h3 className="panel-title">
+      <div className='panel panel-default'>
+        <div className='panel-heading'>
+          <h3 className='panel-title'>
             Queries
             <span className={collapseClass} onClick={this.toggle}></span>
           </h3>
@@ -56,27 +56,32 @@ class QueryOperations extends React.Component {
         <div className={panelBodyClassName}>
           <ul style={{listStyle: 'none', paddingLeft: '0px',
             marginBottom: '0px'}}>
-            <li><Link to="results">All</Link></li>
+            <li><Link to='results'>All</Link></li>
             <li>
-              <Link to="results" query={{category: 'running'}}>
+              <Link to='results' query={{category: 'running'}}>
                 Running
               </Link>
             </li>
             <li>
-              <Link to="results" query={{category: 'successful'}}>
+              <Link to='results' query={{category: 'successful'}}>
                 Completed
               </Link>
             </li>
             <li>
-              <Link to="results" query={{category: 'queued'}}>
+              <Link to='results' query={{category: 'queued'}}>
                 Queued
               </Link>
             </li>
             <li>
-              <Link to="results" query={{category: 'failed'}}>
+              <Link to='results' query={{category: 'failed'}}>
                 Failed
               </Link>
             </li>
+            <li>
+              <Link to='savedqueries'>
+                Saved Queries
+              </Link>
+            </li>
           </ul>
         </div>
       </div>

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryParamRowComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryParamRowComponent.js b/lens-ui/app/components/QueryParamRowComponent.js
new file mode 100644
index 0000000..fb5f5da
--- /dev/null
+++ b/lens-ui/app/components/QueryParamRowComponent.js
@@ -0,0 +1,173 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { Multiselect } from 'react-widgets';
+import assign from 'object-assign';
+import 'react-widgets/dist/css/core.css';
+import 'react-widgets/dist/css/react-widgets.css';
+
+// returns true/false if the default value is correct
+// and also returns the value
+function validate (val, dataType) {
+  // if (dataType === 'NUMBER' && !window.isNaN(val)) return [true, val];
+  // if (dataType === 'BOOLEAN' && (val === 'true' || val === 'false')) {
+  //   return [true, val];
+  // }
+  // if (dataType === 'STRING' && typeof val === 'string') return [true, val];
+
+  return [true, val];
+}
+
+class QueryParamRow extends React.Component {
+  constructor (props) {
+    super(props);
+
+    // state being decided by mode of use of this component
+    // `entryMode` is used by the SavedQueryPreviewComponent,
+    // to just add values and run the saved query.
+    if (props.entryMode) {
+      this.state = assign({}, props.param);
+    } else {
+      this.state = assign({}, props.param, {
+        dataType: 'STRING',
+        collectionType: 'SINGLE',
+        displayName: props.param.name
+      });
+    }
+
+    this.changeDisplayName = this.changeDisplayName.bind(this);
+    this.changeDataType = this.changeDataType.bind(this);
+    this.changeCollectionType = this.changeCollectionType.bind(this);
+    this.changeDefaultValue = this.changeDefaultValue.bind(this);
+    this.addDefaultValue = this.addDefaultValue.bind(this);
+    this.preventEnter = this.preventEnter.bind(this);
+  }
+
+  componentWillReceiveProps (props) {
+    this.setState(assign({}, props.param));
+  }
+
+  componentWillUpdate (props, state) {
+    this.props.updateParam({
+      name: props.param.name,
+      param: state
+    });
+  }
+
+  render () {
+    let param = this.props.param;
+
+    return (
+      <tr>
+        <td>{param.name}</td>
+        <td>
+          { this.props.entryMode ? param.displayName :
+            <input type='text' className='form-control' required defaultValue={param.name}
+              placeholder='display name' onChange={this.changeDisplayName}/>
+          }
+        </td>
+        <td>
+          { this.props.entryMode ? param.dataType :
+            <select className='form-control' defaultValue='STRING'
+              onChange={this.changeDataType}>
+              <option value='STRING'>String</option>
+              <option value='NUMBER'>Number</option>
+              <option value='BOOLEAN'>Boolean</option>
+            </select>
+          }
+        </td>
+        <td>
+          { this.props.entryMode ? param.collectionType :
+            <select className='form-control' required defaultValue='SINGLE'
+              onChange={this.changeCollectionType}>
+              <option value='SINGLE'>Single</option>
+              <option value='MULTIPLE'>Multiple</option>
+            </select>
+          }
+
+        </td>
+        <td>
+          { !this.props.entryMode && (this.state.collectionType === 'SINGLE' ?
+            <input type='text' className='form-control' required value={this.state.defaultValue}
+              placeholder='default value' onChange={this.changeDefaultValue}/> :
+            <Multiselect messages={{createNew: 'Enter to add'}}
+              onCreate={this.addDefaultValue}
+              defaultValue={this.state.defaultValue} onKeyDown={this.preventEnter}
+            />
+          )}
+
+          { this.props.entryMode && (param.collectionType === 'SINGLE' ?
+            <input type='text' className='form-control' required value={this.state.defaultValue}
+              placeholder='default value' onChange={this.changeDefaultValue}/> :
+            <Multiselect messages={{createNew: 'Enter to add'}}
+               onCreate={this.addDefaultValue}
+              defaultValue={this.state.defaultValue} onKeyDown={this.preventEnter}
+            />
+          )}
+        </td>
+      </tr>
+    );
+  }
+
+  // these methods change the default values
+  // called by normal input
+  changeDefaultValue (e) {
+    let val = validate(e.target.value, this.state.dataType);
+
+    if (val[0]) this.setState({defaultValue: val[1]});
+  }
+
+  // called my multiselect
+  addDefaultValue (item) {
+    let val = validate(item, this.state.dataType);
+
+    if (val[0]) {
+      this.state.defaultValue.push(val[1]);
+      this.setState(this.state);
+    }
+  }
+
+  preventEnter (e) {
+    if (e.keyCode == 13) e.preventDefault();
+  }
+
+  changeDataType (e) {
+    let val = this.state.collectionType === 'SINGLE' ? null : [];
+    this.setState({dataType: e.target.value, defaultValue: val});
+  }
+
+  changeCollectionType (e) {
+    let val = e.target.value === 'MULTIPLE' ? [] : null;
+    this.setState({defaultValue: val});
+    this.setState({collectionType: e.target.value});
+  }
+
+  changeDisplayName (e) {
+    this.setState({displayName: e.target.value});
+  }
+}
+
+QueryParamRow.propTypes = {
+  param: React.PropTypes.object.isRequired,
+  updateParam: React.PropTypes.func.isRequired,
+  entryMode: React.PropTypes.boolean
+};
+
+export default QueryParamRow;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryParamsComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryParamsComponent.js b/lens-ui/app/components/QueryParamsComponent.js
new file mode 100644
index 0000000..a49e338
--- /dev/null
+++ b/lens-ui/app/components/QueryParamsComponent.js
@@ -0,0 +1,130 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { Button, Input } from 'react-bootstrap';
+import _ from 'lodash';
+
+import QueryParamRow from './QueryParamRowComponent';
+
+class QueryParams extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {description: '', childrenParams: {}, runImmediately: false};
+
+    this.close = this.close.bind(this);
+    this.save = this.save.bind(this);
+    this.update = this.update.bind(this);
+    this.handleChange = this.handleChange.bind(this);
+    this.handleCheck = this.handleCheck.bind(this);
+    this._getChildrenParams = this._getChildrenParams.bind(this);
+  }
+
+  componentWillReceiveProps (props) {
+    if (!_.isEqual(props.params, this.props.params)) {
+      this.state.childrenParams = {};
+    }
+  }
+
+  render () {
+    let params = this.props.params && this.props.params.map((param, index) => {
+      return <QueryParamRow key={param.name} param={param} updateParam={this.update}/>;
+    });
+
+    if (!params) return null;
+
+    return (
+      <form onSubmit={this.save} style={{padding: '10px', boxShadow: '2px 2px 2px 2px grey',
+        marginTop: '6px', backgroundColor: 'rgba(255, 255, 0, 0.1)'}}>
+        <h3>
+          Query Parameters
+        </h3>
+        <table className='table table-striped'>
+          <thead>
+            <tr>
+              <th>Parameter</th>
+              <th>Display Name</th>
+              <th>Data Type</th>
+              <th>Collection Type</th>
+              <th>Value</th>
+            </tr>
+          </thead>
+          <tbody>
+            {params}
+          </tbody>
+        </table>
+        <div className='form-group'>
+          <label className='sr-only' htmlFor='queryDescription'>Description</label>
+          <input type='text' className='form-control' style={{fontWeight: 'normal'}}
+            onChange={this.handleChange} id='queryDescription'
+            placeholder='(Optional description) e.g. This awesome query does magic along with its job.'
+          />
+        </div>
+        <div>
+            <Input type='checkbox' label='Run after saving'
+              onChange={this.handleCheck} />
+
+        </div>
+        <Button bsStyle='primary' type='submit'>Save</Button>
+        <Button onClick={this.close} style={{marginLeft: '4px'}}>Cancel</Button>
+      </form>
+    );
+  }
+
+  close () {
+    this.props.close();
+  }
+
+  save (e) {
+    e.preventDefault();
+    var parameters = this._getChildrenParams();
+    this.props.saveParams({
+      parameters: parameters,
+      description: this.state.description,
+      runImmediately: this.state.runImmediately
+    });
+  }
+
+  _getChildrenParams () {
+    return Object.keys(this.state.childrenParams).map(name => {
+      return this.state.childrenParams[name];
+    });
+  }
+
+  handleChange (e) {
+    this.setState({description: e.target.value});
+  }
+
+  handleCheck (e) {
+    this.setState({runImmediately: e.target.checked});
+  }
+
+  // called by the child component {name, param}
+  update (param) {
+    this.state.childrenParams[param.name] = param.param;
+  }
+}
+
+QueryParams.propTypes = {
+  params: React.PropTypes.array.isRequired,
+  close: React.PropTypes.func.isRequired,
+  saveParams: React.PropTypes.func.isRequired
+};
+
+export default QueryParams;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryPreviewComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryPreviewComponent.js b/lens-ui/app/components/QueryPreviewComponent.js
index fabe383..a29f2d8 100644
--- a/lens-ui/app/components/QueryPreviewComponent.js
+++ b/lens-ui/app/components/QueryPreviewComponent.js
@@ -24,13 +24,12 @@ import CodeMirror from 'codemirror';
 import 'codemirror/mode/sql/sql.js';
 import 'codemirror/addon/runmode/runmode.js';
 
-import Loader from '../components/LoaderComponent';
 import UserStore from '../stores/UserStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
 
 class QueryPreview extends React.Component {
   constructor (props) {
-    super (props);
+    super(props);
     this.state = {showDetail: false};
     this.toggleQueryDetails = this.toggleQueryDetails.bind(this);
     this.cancelQuery = this.cancelQuery.bind(this);
@@ -48,11 +47,9 @@ class QueryPreview extends React.Component {
     CodeMirror
       .runMode(query.userQuery,
         'text/x-mysql', function (text, style) {
-
         // this method is called for every token and gives the
         // token and style class for it.
         codeTokens.push(<span className={'cm-' + style}>{text}</span>);
-
       });
 
     // figuring out the className for query status
@@ -70,36 +67,35 @@ class QueryPreview extends React.Component {
     let statusClass = 'label-' + statusTypes[query.status.status] ||
       'label-info';
     let handle = query.queryHandle.handleId;
-    let executionTime = (query.finishTime - query.submissionTime)/(1000*60);
-    let statusType = query.status.status === 'ERROR'? 'Error: ' : 'Status: ';
+    let executionTime = (query.finishTime - query.submissionTime) / (1000 * 60);
+    let statusType = query.status.status === 'ERROR' ? 'Error: ' : 'Status: ';
     let seeResult = '';
-    let statusMessage = query.status.status === 'SUCCESSFUL'?
+    let statusMessage = query.status.status === 'SUCCESSFUL' ?
       query.status.statusMessage :
       query.status.errorMessage;
 
     if (query.status.status === 'SUCCESSFUL') {
-      seeResult = (<Link to="result" params={{handle: handle}}
-        className="btn btn-success btn-xs pull-right" style={{marginLeft: '5px'}}>
+      seeResult = (<Link to='result' params={{handle: handle}}
+        className='btn btn-success btn-xs pull-right' style={{marginLeft: '5px'}}>
         See Result
       </Link>);
     }
 
-
     return (
       <section>
-        <div className="panel panel-default">
-          <pre className="cm-s-default" style={{cursor: 'pointer',
+        <div className='panel panel-default'>
+          <pre className='cm-s-default' style={{cursor: 'pointer',
             border: '0px', marginBottom: '0px'}}
             onClick={this.toggleQueryDetails}>
 
             {codeTokens}
 
-            <label className={"pull-right label " + statusClass}>
+            <label className={'pull-right label ' + statusClass}>
               {query.status.status}
             </label>
 
             {query.queryName && (
-              <label className="pull-right label label-primary"
+              <label className='pull-right label label-primary'
                 style={{marginRight: '5px'}}>
                 {query.queryName}
               </label>
@@ -108,32 +104,31 @@ class QueryPreview extends React.Component {
           </pre>
 
           {this.state.showDetail && (
-            <div className="panel-body" style={{borderTop: '1px solid #cccccc',
+            <div className='panel-body' style={{borderTop: '1px solid #cccccc',
             paddingBottom: '0px'}} key={'preview' + handle}>
-              <div className="row">
-                <div className="col-lg-4 col-sm-4">
-                  <span className="text-muted">Name </span>
+              <div className='row'>
+                <div className='col-lg-4 col-sm-4'>
+                  <span className='text-muted'>Name </span>
                   <strong>{ query.queryName || 'Not specified'}</strong>
                 </div>
-                <div className="col-lg-4 col-sm-4">
-                  <span className="text-muted">Submitted </span>
+                <div className='col-lg-4 col-sm-4'>
+                  <span className='text-muted'>Submitted </span>
                   <strong>
                     { Moment(query.submissionTime).format('Do MMM YY, hh:mm:ss a')}
                   </strong>
                 </div>
-                <div className="col-lg-4 col-sm-4">
-                  <span className="text-muted">Execution time </span>
+                <div className='col-lg-4 col-sm-4'>
+                  <span className='text-muted'>Execution time </span>
                   <strong>
 
                     { executionTime > 0 ?
-                        Math.ceil(executionTime) +
-                          (executionTime > 1 ? ' mins': ' min') :
-                        'Still running'
+                      Math.ceil(executionTime) +
+                        (executionTime > 1 ? ' mins' : ' min') : 'Still running'
                     }
                   </strong>
                 </div>
               </div>
-              <div className="row">
+              <div className='row'>
                 <div
                   className={'alert alert-' + statusTypes[query.status.status]}
                   style={{marginBottom: '0px', padding: '5px 15px 5px 15px'}}>
@@ -143,8 +138,8 @@ class QueryPreview extends React.Component {
 
                       {seeResult}
 
-                      <Link to="query" query={{handle: query.queryHandle.handleId}}
-                        className="pull-right">
+                      <Link to='query' query={{handle: query.queryHandle.handleId}}
+                        className='pull-right'>
                         Edit Query
                       </Link>
 
@@ -167,10 +162,14 @@ class QueryPreview extends React.Component {
     let handle = this.props && this.props.queryHandle &&
       this.props.queryHandle.handleId;
 
-    if (!handle)  return;
+    if (!handle) return;
 
     AdhocQueryActions.cancelQuery(secretToken, handle);
   }
 }
 
+QueryPreview.propTypes = {
+  queryHandle: React.PropTypes.string
+};
+
 export default QueryPreview;


[42/50] [abbrv] lens git commit: LENS-796 : Slow response times for /metastore/nativetables API

Posted by ra...@apache.org.
LENS-796 : Slow response times for /metastore/nativetables API


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/5c9bae09
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/5c9bae09
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/5c9bae09

Branch: refs/heads/current-release-line
Commit: 5c9bae096351960f4790e11f76a5d7665d8e8d3d
Parents: aeaae68
Author: Deepak Barr <de...@gmail.com>
Authored: Tue Oct 6 12:52:29 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Tue Oct 6 12:52:29 2015 +0530

----------------------------------------------------------------------
 .../metastore/CubeMetastoreServiceImpl.java     | 60 ++++++++++----------
 1 file changed, 30 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/5c9bae09/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java
index 37cebfe..4c8b525 100644
--- a/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java
@@ -38,14 +38,13 @@ import org.apache.lens.server.api.metastore.CubeMetastoreService;
 import org.apache.lens.server.session.LensSessionImpl;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
 import org.apache.hadoop.hive.metastore.api.*;
 import org.apache.hadoop.hive.ql.metadata.*;
 import org.apache.hadoop.hive.ql.metadata.Partition;
 import org.apache.hadoop.hive.ql.metadata.Table;
 import org.apache.hadoop.hive.ql.parse.ParseException;
 import org.apache.hive.service.cli.CLIService;
-import org.apache.hive.service.cli.HiveSQLException;
-import org.apache.thrift.TException;
 
 import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
@@ -1198,28 +1197,37 @@ public class CubeMetastoreServiceImpl extends BaseLensService implements CubeMet
     }
   }
 
-  private List<String> getTablesFromDB(LensSessionHandle sessionid,
-    String dbName, boolean prependDbName)
-    throws MetaException, UnknownDBException, HiveSQLException, TException, LensException {
-    List<String> tables = getSession(sessionid).getMetaStoreClient().getAllTables(
-      dbName);
-    List<String> result = new ArrayList<String>();
-    if (tables != null && !tables.isEmpty()) {
-      Iterator<String> it = tables.iterator();
-      while (it.hasNext()) {
-        String tblName = it.next();
-        org.apache.hadoop.hive.metastore.api.Table tbl =
-          getSession(sessionid).getMetaStoreClient().getTable(dbName, tblName);
-        if (tbl.getParameters().get(MetastoreConstants.TABLE_TYPE_KEY) == null) {
-          if (prependDbName) {
-            result.add(dbName + "." + tblName);
-          } else {
-            result.add(tblName);
+  private List<String> getNativeTablesFromDB(LensSessionHandle sessionid, String dbName, boolean prependDbName)
+    throws LensException {
+    IMetaStoreClient msc = null;
+    try {
+      msc = getSession(sessionid).getMetaStoreClient();
+      List<String> tables = msc.getAllTables(
+        dbName);
+      List<String> result = new ArrayList<String>();
+      if (tables != null && !tables.isEmpty()) {
+        List<org.apache.hadoop.hive.metastore.api.Table> tblObjects =
+          msc.getTableObjectsByName(dbName, tables);
+        Iterator<org.apache.hadoop.hive.metastore.api.Table> it = tblObjects.iterator();
+        while (it.hasNext()) {
+          org.apache.hadoop.hive.metastore.api.Table tbl = it.next();
+          if (tbl.getParameters().get(MetastoreConstants.TABLE_TYPE_KEY) == null) {
+            if (prependDbName) {
+              result.add(dbName + "." + tbl.getTableName());
+            } else {
+              result.add(tbl.getTableName());
+            }
           }
         }
       }
+      return result;
+    } catch (Exception e) {
+      throw new LensException("Error getting native tables from DB", e);
+    } finally {
+      if (null != msc) {
+        msc.close();
+      }
     }
-    return result;
   }
 
   @Override
@@ -1240,24 +1248,16 @@ public class CubeMetastoreServiceImpl extends BaseLensService implements CubeMet
       }
       List<String> tables;
       if (!StringUtils.isBlank(dbName)) {
-        tables = getTablesFromDB(sessionid, dbName, false);
+        tables = getNativeTablesFromDB(sessionid, dbName, false);
       } else {
         log.info("Getting tables from all dbs");
         List<String> alldbs = getAllDatabases(sessionid);
         tables = new ArrayList<String>();
         for (String db : alldbs) {
-          tables.addAll(getTablesFromDB(sessionid, db, true));
+          tables.addAll(getNativeTablesFromDB(sessionid, db, true));
         }
       }
       return tables;
-    } catch (HiveSQLException e) {
-      throw new LensException(e);
-    } catch (MetaException e) {
-      throw new LensException(e);
-    } catch (UnknownDBException e) {
-      throw new NotFoundException("Database " + dbName + " does not exist");
-    } catch (TException e) {
-      throw new LensException(e);
     } catch (HiveException e) {
       throw new LensException(e);
     } finally {


[05/50] [abbrv] lens git commit: Revert "LENS-753: Queue number for queries in submitted queue"

Posted by ra...@apache.org.
Revert "LENS-753: Queue number for queries in submitted queue"

This reverts commit 2f22f60b2d50c20ec9291483d73d4fd735eb8ef9.


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

Branch: refs/heads/current-release-line
Commit: fe44e69fdbdff24b3344071a268e7602077575cc
Parents: 2f22f60
Author: Amareshwari Sriramadasu <am...@apache.org>
Authored: Fri Aug 28 12:40:30 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Fri Aug 28 12:40:30 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryStatus.java  | 11 -------
 .../lens/cli/commands/LensQueryCommands.java    |  3 --
 .../server/api/driver/DriverQueryStatus.java    | 14 ++-------
 .../server/api/query/FinishedLensQuery.java     |  2 +-
 .../lens/server/api/query/QueryContext.java     |  2 +-
 .../query/collect/ImmutableQueryCollection.java |  6 ----
 .../server/query/QueryExecutionServiceImpl.java | 15 +++++-----
 .../DefaultEstimatedQueryCollection.java        |  5 ----
 .../query/collect/DefaultQueryCollection.java   | 20 -------------
 .../query/collect/MutableQueryCollection.java   |  1 -
 .../ThreadSafeEstimatedQueryCollection.java     |  5 ----
 .../collect/ThreadSafeQueryCollection.java      |  5 ----
 .../collect/DefaultQueryCollectionTest.java     | 23 ---------------
 .../server/query/collect/QueryCollectUtil.java  | 30 --------------------
 14 files changed, 12 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
index 0d73c3f..9614caa 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
@@ -39,8 +39,6 @@ import lombok.*;
  *
  * @param progress
  *          the progress
- * @param queueNumber
- *          the queue number
  * @param status
  *          the status
  * @param statusMessage
@@ -123,14 +121,6 @@ public class QueryStatus implements Serializable {
   private double progress;
 
   /**
-   * The running queue number. A non zero value gives the queue number. Queue number zero mean either the query is in
-   * waiting or completed state.
-   */
-  @XmlElement
-  @Getter
-  private int queueNumber;
-
-  /**
    * The status.
    */
   @XmlElement
@@ -178,7 +168,6 @@ public class QueryStatus implements Serializable {
     StringBuilder str = new StringBuilder(status.toString()).append(':').append(statusMessage);
     if (status.equals(Status.RUNNING)) {
       str.append(" - Progress:").append(progress).append(":").append(progressMessage);
-      str.append(" - Queue number:").append(queueNumber);
     }
     if (status.equals(Status.SUCCESSFUL)) {
       if (isResultSetAvailable) {

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 5f90060..7a5b177 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -170,9 +170,6 @@ public class LensQueryCommands extends BaseLensCommand {
         sb.append("Progress Message : ").append(status.getProgressMessage()).append("\n");
       }
     }
-    if (status.getQueueNumber() != 0) {
-      sb.append("Queue Number : ").append(status.getQueueNumber()).append("\n");
-    }
 
     if (status.getErrorMessage() != null) {
       sb.append("Error : ").append(status.getErrorMessage()).append("\n");

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
index 48a841b..f78b7c3 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
@@ -89,13 +89,6 @@ public class DriverQueryStatus implements Serializable {
   private double progress = 0.0f;
 
   /**
-   * The running queue number.
-   */
-  @Getter
-  @Setter
-  private int queueNumber = 0;
-
-  /**
    * The state.
    */
   @Getter
@@ -174,8 +167,7 @@ public class DriverQueryStatus implements Serializable {
       break;
     }
 
-    return new QueryStatus(progress, queueNumber, qstate, statusMessage, isResultSetAvailable, progressMessage,
-            errorMessage, null);
+    return new QueryStatus(progress, qstate, statusMessage, isResultSetAvailable, progressMessage, errorMessage, null);
   }
 
   /**
@@ -186,8 +178,8 @@ public class DriverQueryStatus implements Serializable {
    * @return the query status
    */
   public static QueryStatus createQueryStatus(QueryStatus.Status state, DriverQueryStatus dstatus) {
-    return new QueryStatus(dstatus.progress, dstatus.queueNumber, state, dstatus.statusMessage,
-            dstatus.isResultSetAvailable, dstatus.progressMessage, dstatus.errorMessage, null);
+    return new QueryStatus(dstatus.progress, state, dstatus.statusMessage, dstatus.isResultSetAvailable,
+      dstatus.progressMessage, dstatus.errorMessage, null);
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
index c9b8854..6cecf7e 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
@@ -204,7 +204,7 @@ public class FinishedLensQuery {
     qctx.setQueryHandle(QueryHandle.fromString(handle));
     qctx.setLaunchTime(this.startTime);
     qctx.setEndTime(getEndTime());
-    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, 0, QueryStatus.Status.valueOf(getStatus()),
+    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, QueryStatus.Status.valueOf(getStatus()),
         getErrorMessage() == null ? "" : getErrorMessage(), getResult() != null, null, null, null));
     qctx.getDriverStatus().setDriverStartTime(getDriverStartTime());
     qctx.getDriverStatus().setDriverFinishTime(getDriverEndTime());

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index 0906b83..beaa72f 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -217,7 +217,7 @@ public class QueryContext extends AbstractQueryContext {
     super(userQuery, user, qconf, conf, drivers, mergeDriverConf);
     this.submissionTime = submissionTime;
     this.queryHandle = new QueryHandle(UUID.randomUUID());
-    this.status = new QueryStatus(0.0f, 0, Status.NEW, "Query just got created", false, null, null, null);
+    this.status = new QueryStatus(0.0f, Status.NEW, "Query just got created", false, null, null, null);
     this.priority = Priority.NORMAL;
     this.lensConf = qconf;
     this.conf = conf;

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
index 4e3c95b..344ff10 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
@@ -50,10 +50,4 @@ public interface ImmutableQueryCollection {
    * @return Count of existing queries
    */
   int getQueriesCount();
-
-  /**
-   *
-   * @return Index of a query within collection
-   */
-  int getQueryIndex(final QueryContext query);
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index b23e0df..c29a1ac 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -615,8 +615,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
       checkEstimatedQueriesState(query);
       QueryStatus oldStatus = query.getStatus();
-      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), query.getStatus().getQueueNumber(),
-        QueryStatus.Status.LAUNCHED, "Query is launched on driver", false, null, null, null);
+      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), QueryStatus.Status.LAUNCHED,
+          "Query is launched on driver", false, null, null, null);
       query.validateTransition(newStatus);
 
       // Check if we need to pass session's effective resources to selected driver
@@ -717,7 +717,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, 0, FAILED, statusMsg, false, null, reason, lensErrorTO));
+    ctx.setStatus(new QueryStatus(0.0f, FAILED, statusMsg, false, null, reason, lensErrorTO));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -731,7 +731,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    */
   private void setCancelledStatus(QueryContext ctx, String statusMsg) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, 0, CANCELED, statusMsg, false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0f, CANCELED, statusMsg, false, null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -765,7 +765,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
   void setSuccessState(QueryContext ctx) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(1.0f, 0, SUCCESSFUL, "Query is successful!", ctx
+    ctx.setStatus(new QueryStatus(1.0f, SUCCESSFUL, "Query is successful!", ctx
       .isResultAvailableInDriver(), null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
@@ -786,7 +786,6 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           log.info("Updating status for {}", ctx.getQueryHandle());
           try {
             ctx.getSelectedDriver().updateStatus(ctx);
-            ctx.getDriverStatus().setQueueNumber(launchedQueries.getQueryIndex(ctx));
             ctx.setStatus(ctx.getDriverStatus().toQueryStatus());
           } catch (LensException exc) {
             // Driver gave exception while updating status
@@ -947,7 +946,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             resultSets.remove(finished.getCtx().getQueryHandle());
           }
           fireStatusChangeEvent(finished.getCtx(),
-            new QueryStatus(1f, 0, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
+            new QueryStatus(1f, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
           log.info("Query purged: {}", finished.getCtx().getQueryHandle());
 
         } catch (LensException e) {
@@ -1701,7 +1700,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   private QueryHandle submitQuery(final QueryContext ctx) throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0, 0, QUEUED, "Query is queued", false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0, QUEUED, "Query is queued", false, null, null, null));
     queuedQueries.add(ctx);
     log.debug("Added to Queued Queries:{}", ctx.getQueryHandleString());
     allQueries.put(ctx.getQueryHandle(), ctx);

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
index bd27de8..e3505bb 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
@@ -138,11 +138,6 @@ public class DefaultEstimatedQueryCollection implements EstimatedQueryCollection
     return this.queries.getQueriesCount();
   }
 
-  @Override
-  public int getQueryIndex(QueryContext query) {
-    return this.queries.getQueryIndex(query);
-  }
-
   @VisibleForTesting
   void checkState(final QueryContext query) {
     Preconditions.checkState(query.getSelectedDriver() != null);

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
index 0387cce..f9e7701 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
@@ -96,26 +96,6 @@ public class DefaultQueryCollection implements QueryCollection {
     return queries.size();
   }
 
-
-  /**
-   *  Since the collection is a linkedHashSet, the order of queries is always maintained.
-   * @param query
-   * @return
-   */
-  @Override
-  public int getQueryIndex(QueryContext query) {
-    Iterator iterator = queries.iterator();
-    int index = 1;
-    while (iterator.hasNext()) {
-      QueryContext queuedQuery = (QueryContext) iterator.next();
-      if (queuedQuery.getQueryHandle().equals(query.getQueryHandle())) {
-        return index;
-      }
-      index += 1;
-    }
-    return 0;
-  }
-
   private Collection<QueryContext> getQueriesCollectionForUser(final String user) {
 
     final Collection<QueryContext> userQueries = queriesByUser.getCollection(user);

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
index de0779a..e6e777c 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
@@ -62,5 +62,4 @@ public interface MutableQueryCollection {
    * @param queries
    */
   boolean removeAll(final Set<QueryContext> queries);
-
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
index 5b80296..cdbd2ad 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
@@ -70,11 +70,6 @@ public class ThreadSafeEstimatedQueryCollection implements EstimatedQueryCollect
   }
 
   @Override
-  public synchronized int getQueryIndex(QueryContext query) {
-    return this.estimatedQueries.getQueryIndex(query);
-  }
-
-  @Override
   public synchronized boolean add(QueryContext query) {
     return this.estimatedQueries.add(query);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
index 4d5c7a1..7b43a38 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
@@ -72,9 +72,4 @@ public class ThreadSafeQueryCollection implements QueryCollection {
   public synchronized int getQueriesCount() {
     return this.queries.getQueriesCount();
   }
-
-  @Override
-  public synchronized int getQueryIndex(QueryContext query) {
-    return this.queries.getQueryIndex(query);
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
index f55094a..7a81e83 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
@@ -34,7 +34,6 @@ import org.testng.annotations.Test;
 public class DefaultQueryCollectionTest {
 
   private static final String MOCK_USER = "MockUserEmail";
-  private static final String MOCK_HANDLE = "0-0-0-0-";
 
   /* Note: Since verification of addition/removal required calling get methods,
   hence methods getQueriesCount and getQueries(user) are indirectly getting tested in these tests */
@@ -77,28 +76,6 @@ public class DefaultQueryCollectionTest {
   }
 
   @Test
-  public void testRemoveMethodMustChangeQueryIndices() {
-
-    /* Initialization */
-    final int noOfQueriesUsedInTest = 10;
-    QueryCollection queries = createQueriesInstanceWithQueryHandleStubbing(noOfQueriesUsedInTest, MOCK_HANDLE);
-
-    QueryContext completedQuery = getMockedQueryFromQueries(queries.getQueries(), MOCK_HANDLE, 4);
-    QueryContext runningQuery = getMockedQueryFromQueries(queries.getQueries(), MOCK_HANDLE, 5);
-
-    /* Execution */
-    queries.remove(completedQuery);
-
-     /* Verification 1: Verifies that queries were removed from queries list by calling getQueriesCount which gets
-    results from queries list */
-    assertEquals(queries.getQueriesCount(), 9);
-
-    /* Verification 2: Verifies that query index is decreased after removal of queries which were present before
-     them in the queries list */
-    assertEquals(queries.getQueryIndex(runningQuery), 4);
-  }
-
-  @Test
   public void testGetQueriesMustReturnCopyOfUnderlyingCollection() {
 
     /* Initialization */

http://git-wip-us.apache.org/repos/asf/lens/blob/fe44e69f/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
index 63d1508..51fcf00 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
@@ -27,10 +27,8 @@ import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertTrue;
 
 import java.lang.reflect.Method;
-import java.util.Iterator;
 import java.util.Set;
 
-import org.apache.lens.api.query.QueryHandle;
 import org.apache.lens.server.api.query.QueryContext;
 
 import com.google.common.collect.Sets;
@@ -79,34 +77,6 @@ public class QueryCollectUtil {
     return new DefaultQueryCollection(mockQueries);
   }
 
-  public static QueryCollection createQueriesInstanceWithQueryHandleStubbing(final int reqNoOfMockQueries,
-    final String handlePrefix) {
-
-    Set<QueryContext> mockQueries = Sets.newLinkedHashSet();
-
-    for (int index = 1; index <= reqNoOfMockQueries; ++index) {
-      mockQueries.add(createQueryInstanceWithQueryHandleStubbing(handlePrefix, index));
-    }
-    return new DefaultQueryCollection(mockQueries);
-  }
-
-  public static QueryContext createQueryInstanceWithQueryHandleStubbing(String handlePrefix, int index) {
-    QueryContext mockQuery = mock(QueryContext.class);
-    when(mockQuery.getQueryHandle()).thenReturn(QueryHandle.fromString(handlePrefix + index));
-    return mockQuery;
-  }
-
-  public static QueryContext getMockedQueryFromQueries(Set<QueryContext> queries, String mockHandle, int index) {
-    Iterator iterator = queries.iterator();
-    while (iterator.hasNext()) {
-      QueryContext queuedQuery = (QueryContext) iterator.next();
-      if (queuedQuery.getQueryHandle().equals(QueryHandle.fromString(mockHandle + index))) {
-        return queuedQuery;
-      }
-    }
-    return null;
-  }
-
   public static QueryCollection stubMockQueryAndCreateQueriesInstance(final QueryContext mockQuery,
     final String mockUser) {
 


[48/50] [abbrv] lens git commit: LENS-739: (license fix) Generate udf jar for lens-regression

Posted by ra...@apache.org.
LENS-739:  (license fix) Generate udf jar for lens-regression


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

Branch: refs/heads/current-release-line
Commit: dd33a60589ca1a8efc71c2ceb73af22654b584f3
Parents: d4d4aa2
Author: Archana H <ar...@gmail.com>
Authored: Thu Oct 8 19:32:46 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Thu Oct 8 19:32:46 2015 +0530

----------------------------------------------------------------------
 .../src/additional/java/SampleUdf.java           | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/dd33a605/lens-regression/src/additional/java/SampleUdf.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/additional/java/SampleUdf.java b/lens-regression/src/additional/java/SampleUdf.java
index 2c3e667..e340ffd 100644
--- a/lens-regression/src/additional/java/SampleUdf.java
+++ b/lens-regression/src/additional/java/SampleUdf.java
@@ -1,3 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import org.apache.hadoop.hive.ql.exec.UDF;
 import org.apache.hadoop.io.Text;
 


[13/50] [abbrv] lens git commit: Revert "LENS-737 : Throw single error out with LensMultiException"

Posted by ra...@apache.org.
Revert "LENS-737 : Throw single error out with LensMultiException"

This reverts commit 309a7ed5ddb3f3848ad0efca59b3177beba60dd2.


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

Branch: refs/heads/current-release-line
Commit: fb235faa74bbcf7a00c36aa105bbf636c5213f04
Parents: 309a7ed
Author: raju.bairishetti <ra...@apache.org>
Authored: Tue Sep 8 11:57:30 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Tue Sep 8 11:57:30 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryPlan.java    |  24 ++
 lens-api/src/main/resources/lens-errors.conf    | 325 ++++++++++---------
 .../lens/cli/commands/LensQueryCommands.java    |  83 ++---
 .../apache/lens/cli/ExecuteQueryCommandIT.java  |   4 +-
 .../apache/lens/cli/TestLensQueryCommands.java  |   8 +-
 .../java/org/apache/lens/client/LensClient.java |   6 +-
 .../org/apache/lens/client/LensStatement.java   |  47 +--
 .../ColUnAvailableInTimeRangeException.java     |   6 +-
 .../FieldsCannotBeQueriedTogetherException.java |   6 +-
 .../lens/cube/error/LensCubeErrorCode.java      |  76 ++---
 .../lens/cube/parse/AggregateResolver.java      |   2 +-
 .../apache/lens/cube/parse/AliasReplacer.java   |   7 +-
 .../lens/cube/parse/BetweenTimeRangeWriter.java |   6 +-
 .../lens/cube/parse/CandidateTableResolver.java |  18 +-
 .../apache/lens/cube/parse/ColumnResolver.java  |   4 +-
 .../lens/cube/parse/CubeQueryContext.java       |  15 +-
 .../lens/cube/parse/CubeQueryRewriter.java      |   4 +-
 .../org/apache/lens/cube/parse/DateUtil.java    |   4 +-
 .../cube/parse/DenormalizationResolver.java     |   6 +-
 .../org/apache/lens/cube/parse/HQLParser.java   |   2 +-
 .../apache/lens/cube/parse/JoinResolver.java    |  12 +-
 .../lens/cube/parse/MultiFactHQLContext.java    |   2 +-
 .../org/apache/lens/cube/parse/TimeRange.java   |   5 +-
 .../lens/cube/parse/TimerangeResolver.java      |   8 +-
 .../lens/cube/parse/TestBaseCubeQueries.java    |   4 +-
 .../lens/cube/parse/TestCubeRewriter.java       |  24 +-
 .../lens/cube/parse/TestExpressionResolver.java |   6 +-
 .../lens/cube/parse/TestJoinResolver.java       |   4 +-
 .../lens/cube/parse/TestTimeRangeExtractor.java |   4 +-
 .../lens/cube/parse/TestTimeRangeWriter.java    |   3 +-
 .../parse/TestTimeRangeWriterWithQuery.java     |   2 +-
 .../driver/es/exceptions/ESClientException.java |  17 +-
 .../es/exceptions/InvalidQueryException.java    |  18 +-
 .../apache/lens/server/api/LensErrorInfo.java   |  34 --
 .../lens/server/api/driver/DriverQueryPlan.java |   2 +-
 .../lens/server/api/error/LensException.java    | 102 ++----
 .../api/error/LensMultiCauseException.java      |  20 +-
 .../lens/server/error/LensServerErrorCode.java  |  18 +-
 .../UnSupportedQuerySubmitOpException.java      |   4 +-
 .../server/query/QueryExecutionServiceImpl.java |  29 +-
 .../lens/server/query/QueryServiceResource.java |  33 +-
 .../common/ErrorResponseExpectedData.java       |   2 +-
 .../lens/server/common/FailingQueryDriver.java  |   2 +-
 .../server/query/QueryAPIErrorResponseTest.java |  22 +-
 .../lens/server/query/TestQueryService.java     |  50 +--
 45 files changed, 495 insertions(+), 585 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
index c46972d..164195b 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
@@ -114,8 +114,32 @@ public class QueryPlan extends QuerySubmitResult {
   @Getter
   private QueryCostTO queryCost;
 
+  /**
+   * The error.
+   */
+  @XmlElement
+  @Getter
+  private boolean error = false;
+
+  /**
+   * The error msg.
+   */
+  @XmlElement
+  @Getter
+  private String errorMsg;
+
   public String getPlanString() throws UnsupportedEncodingException {
     return URLDecoder.decode(planString, "UTF-8");
   }
 
+  /**
+   * Instantiates a new query plan.
+   *
+   * @param hasError the has error
+   * @param errorMsg the error msg
+   */
+  public QueryPlan(boolean hasError, String errorMsg) {
+    this.error = hasError;
+    this.errorMsg = errorMsg;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-api/src/main/resources/lens-errors.conf
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/lens-errors.conf b/lens-api/src/main/resources/lens-errors.conf
index 5428041..3fb191e 100644
--- a/lens-api/src/main/resources/lens-errors.conf
+++ b/lens-api/src/main/resources/lens-errors.conf
@@ -83,178 +83,179 @@ lensCubeErrors = [
   {
     errorCode = 3002
     httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "%s. Please remove conflicting fields and try again."
-    payloadClass = org.apache.lens.cube.error.ConflictingFields
-  }
-
-  {
-    errorCode = 3003
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "More than one cube accessed in query : %s and %s"
-  }
-
-  {
-    errorCode = 3004
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Neither cube nor dimensions accessed in the query"
-  }
-
-  {
-    errorCode = 3005
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No timerange filter specified"
-  }
-
-  {
-    errorCode = 3006
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "%s is not timed dimension"
-  }
-
-  {
-    errorCode = 3007
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
-  }
-
-  {
-    errorCode = 3008
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Date value cannot be null or empty"
-  }
-
-  {
-    errorCode = 3009
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Invalid time unit %s"
-  }
-
-  {
-    errorCode = 3010
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Selecting all columns is not supported"
-  }
-
-  {
-    errorCode = 3011
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Ambiguous column %s, in dimensions %s and %s"
-  }
-
-  {
-    errorCode = 3012
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
-  }
-
-  {
-    errorCode = 3013
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "%s : Not a cube column"
-  }
-
-  {
-    errorCode = 3014
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Invalid time range"
-  }
-
-  {
-    errorCode = 3015
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "From date: %s  should be smaller than to date: %s"
-  }
-
-  {
-    errorCode = 3016
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Join target table: %s is neither dimension nor cube"
-  }
-
-  {
-    errorCode = 3017
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Configured timerange writer cannot be used. Reason %s"
-  }
-
-  {
-    errorCode = 3018
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No join condition available"
-  }
-
-  {
-    errorCode = 3019
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Expression %s is not available in any fact"
-  }
-
-  {
-    errorCode = 3020
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Default aggregate is not set for measure: %s"
-  }
-
-  {
-    errorCode = 3021
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No join path defined from %s to %s"
-  }
-
-  {
-    errorCode = 3022
-    httpStatusCode = ${BAD_REQUEST}
     errorMsg = "%s can only be queried %s. Please adjust the selected time range accordingly."
     payloadClass = org.apache.lens.cube.error.ColUnAvailableInTimeRange
   }
 
   {
-    errorCode = 3023
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No dimension table has the queried columns for %s, columns: %s"
-  }
-
-  {
-    errorCode = 3024
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No fact table has the queried columns : %s"
-  }
-
-  {
-    errorCode = 3025
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No reference column available for : %s "
-  }
-
-  {
-    errorCode = 3026
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "Could not find the table containing column: %s"
-  }
-
-  {
-    errorCode = 3027
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
-  }
-
-  {
-    errorCode = 3028
+    errorCode = 3003
     httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No candidate fact table available to answer the query, because %s"
+    errorMsg = "%s. Please remove conflicting fields and try again."
+    payloadClass = org.apache.lens.cube.error.ConflictingFields
   }
 
   {
-    errorCode = 3029
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No candidate dimension storage tables for dimension because %s"
-  }
+   errorCode = 3004
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No reference column available for : %s "
+  }
+
+ {
+   errorCode = 3005
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "More than one cube accessed in query : %s and %s"
+ }
+
+ {
+   errorCode = 3006
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Neither cube nor dimensions accessed in the query"
+ }
+
+ {
+   errorCode = 3007
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No timerange filter specified"
+ }
+
+ {
+   errorCode = 3008
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "%s is not timed dimension"
+ }
+
+ {
+   errorCode = 3009
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
+ }
+
+ {
+   errorCode = 3010
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Date value cannot be null or empty"
+ }
+
+ {
+   errorCode = 3011
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Invalid time unit %s"
+ }
+
+ {
+   errorCode = 3012
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Selecting all columns is not supported"
+ }
+
+ {
+   errorCode = 3013
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Ambiguous column %s, in dimensions %s and %s"
+ }
+
+ {
+   errorCode = 3014
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
+ }
+
+ {
+   errorCode = 3015
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Could not find the table containing column: %s"
+ }
+
+ {
+   errorCode = 3016
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "%s : Not a cube column"
+ }
+
+ {
+   errorCode = 3017
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No candidate fact table available to answer the query, because %s"
+ }
+
+ {
+   errorCode = 3018
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No join condition available"
+ }
+
+ {
+   errorCode = 3019
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No storage table available for candidate fact: %s"
+ }
+
+ {
+   errorCode = 3020
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Default aggregate is not set for measure: %s"
+ }
+
+ {
+   errorCode = 3021
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Invalid time range"
+ }
+
+ {
+   errorCode = 3022
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "From date: %s  should be smaller than to date: %s"
+ }
+
+ {
+   errorCode = 3023
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No join path defined from %s to %s"
+ }
+
+ {
+   errorCode = 3024
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Join target table: %s is neither dimension nor cube"
+ }
+
+ {
+   errorCode = 3025
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No fact table has the queried columns : %s"
+ }
+
+ {
+   errorCode = 3026
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No candidate dimension storage tables for dimension because %s"
+ }
+
+ {
+   errorCode = 3027
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No dimension table has the queried columns for %s, columns: %s"
+ }
+
+ {
+   errorCode = 3028
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
+ }
+
+ {
+   errorCode = 3029
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Configured timerange writer cannot be used. Reason %s"
+ }
+
+ {
+   errorCode = 3030
+   httpStatusCode = ${BAD_REQUEST}
+   errorMsg = "Expression %s is not available in any fact"
+ }
 
-  {
-    errorCode = 3030
-    httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "No storage table available for candidate fact: %s"
-  }
 ]
 
 # Overriding errors in lens-errors.conf via lens-errors-override.conf:

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 44c0c62..7a5b177 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -206,34 +206,26 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param sql      the sql
    * @param location the location
    * @return the string
-   * @throws LensAPIException
    * @throws UnsupportedEncodingException the unsupported encoding exception
    */
-  @CliCommand(value = "query explain", help = "Explain execution plan of query <query-string>. "
-      + "Can optionally save the plan to a file by providing <save_location>")
-  public String explainQuery(@CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
-      @CliOption(key = { "save_location" }, mandatory = false, help = "<save_location>") final File path)
-    throws IOException, LensAPIException {
-    PrettyPrintable cliOutput;
-
-    try {
-      QueryPlan plan = getClient().getQueryPlan(sql).getData();
-      if (path != null && StringUtils.isNotBlank(path.getPath())) {
-        String validPath = getValidPath(path, false, false);
-        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath),
-            Charset.defaultCharset())) {
-          osw.write(plan.getPlanString());
-        }
-        return "Saved to " + validPath;
+  @CliCommand(value = "query explain",
+    help = "Explain execution plan of query <query-string>. Can optionally save the plan"
+      + " to a file by providing <save_location>")
+  public String explainQuery(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
+    @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") final File path)
+    throws IOException {
+    QueryPlan plan = getClient().getQueryPlan(sql);
+    if (plan.isError()) {
+      return "Explain FAILED:" + plan.getErrorMsg();
+    }
+    if (path != null && StringUtils.isNotBlank(path.getPath())) {
+      String validPath = getValidPath(path, false, false);
+      try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath), Charset.defaultCharset())) {
+        osw.write(plan.getPlanString());
       }
-      return plan.getPlanString();
-    } catch (final LensAPIException e) {
-      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
-      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
-    } catch (final LensBriefErrorException e) {
-      cliOutput = e.getIdBriefErrorTemplate();
+      return "Saved to " + validPath;
     }
-    return cliOutput.toPrettyString();
+    return plan.getPlanString();
   }
 
   /**
@@ -454,47 +446,36 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param queryName the query name
    * @return the string
    * @throws UnsupportedEncodingException the unsupported encoding exception
-   * @throws LensAPIException
    */
   @CliCommand(value = "prepQuery prepare",
     help = "Prepapre query <query-string> and return prepare handle. Can optionaly provide <query-name>")
   public String prepare(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
     @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException, LensAPIException {
-    return getClient().prepare(sql, queryName).getData().toString();
+    throws UnsupportedEncodingException {
+    return getClient().prepare(sql, queryName).toString();
   }
 
   /**
    * Explain and prepare.
    *
-   * @param sql
-   *          the sql
-   * @param queryName
-   *          the query name
+   * @param sql       the sql
+   * @param queryName the query name
    * @return the string
-   * @throws UnsupportedEncodingException
-   *           the unsupported encoding exception
-   * @throws LensAPIException
+   * @throws UnsupportedEncodingException the unsupported encoding exception
    */
-  @CliCommand(value = "prepQuery explain", help = "Explain and prepare query <query-string>. "
-      + "Can optionally provide <query-name>")
+  @CliCommand(value = "prepQuery explain",
+    help = "Explain and prepare query <query-string>. Can optionally provide <query-name>")
   public String explainAndPrepare(
+    @CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
+    @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
+    throws UnsupportedEncodingException {
 
-  @CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
-      @CliOption(key = { "name" }, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException, LensAPIException {
-    PrettyPrintable cliOutput;
-    try {
-      QueryPlan plan = getClient().explainAndPrepare(sql, queryName).getData();
-      StringBuilder planStr = new StringBuilder(plan.getPlanString());
-      planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
-      return planStr.toString();
-    } catch (final LensAPIException e) {
-      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
-      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
-    } catch (final LensBriefErrorException e) {
-      cliOutput = e.getIdBriefErrorTemplate();
+    QueryPlan plan = getClient().explainAndPrepare(sql, queryName);
+    if (plan.isError()) {
+      return "Explain FAILED:" + plan.getErrorMsg();
     }
-    return cliOutput.toPrettyString();
+    StringBuilder planStr = new StringBuilder(plan.getPlanString());
+    planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
+    return planStr.toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
index 7f8b091..b3fcccb 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
@@ -23,9 +23,11 @@ import static org.testng.Assert.assertTrue;
 import org.apache.lens.cli.commands.LensQueryCommands;
 import org.apache.lens.client.LensClient;
 
+import org.testng.annotations.Test;
+
 public class ExecuteQueryCommandIT extends LensCliApplicationTest {
 
- // @Test
+  @Test
   public void testExecuteSyncQueryWithSyntaxError() {
 
     LensQueryCommands lensQueryCommands = new LensQueryCommands();

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
index 308c036..7a437a1 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
@@ -83,11 +83,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    //testExplainFailQuery(qCom);
+    testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    //testFailPreparedQuery(qCom);
+    testFailPreparedQuery(qCom);
     // run all query commands with query metrics enabled.
     client = new LensClient();
     client.setConnectionParam("lens.query.enable.persistent.resultset.indriver", "false");
@@ -99,11 +99,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    //testExplainFailQuery(qCom);
+    testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    //testFailPreparedQuery(qCom);
+    testFailPreparedQuery(qCom);
   }
 
 

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-client/src/main/java/org/apache/lens/client/LensClient.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
index 5fd04c4..afc76e5 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
@@ -207,7 +207,7 @@ public class LensClient {
     return getQueryDetails(QueryHandle.fromString(handle));
   }
 
-  public LensAPIResult<QueryPlan> getQueryPlan(String q) throws LensAPIException {
+  public QueryPlan getQueryPlan(String q) {
     return new LensStatement(connection).explainQuery(q);
   }
 
@@ -569,11 +569,11 @@ public class LensClient {
     return mc.updatePartitionsOfDimensionTable(table, storage, partsSpec);
   }
 
-  public LensAPIResult<QueryPrepareHandle> prepare(String sql, String queryName) throws LensAPIException {
+  public QueryPrepareHandle prepare(String sql, String queryName) {
     return statement.prepareQuery(sql, queryName);
   }
 
-  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
+  public QueryPlan explainAndPrepare(String sql, String queryName) {
     return statement.explainAndPrepare(sql, queryName);
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
index 0a511f0..397bd82 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
@@ -127,9 +127,8 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query prepare handle
-   * @throws LensAPIException
    */
-  public LensAPIResult<QueryPrepareHandle> prepareQuery(String sql, String queryName) throws LensAPIException {
+  public QueryPrepareHandle prepareQuery(String sql, String queryName) {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -137,14 +136,11 @@ public class LensStatement {
     Client client = connection.buildClient();
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    Response response = target.request().post(Entity.entity(prepareForm(sql, "PREPARE", queryName),
-        MediaType.MULTIPART_FORM_DATA_TYPE));
-
-    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
-      return response.readEntity(new GenericType<LensAPIResult<QueryPrepareHandle>>() {});
-    }
-
-    throw new LensAPIException(response.readEntity(LensAPIResult.class));
+    QueryPrepareHandle handle = target.request().post(
+        Entity.entity(prepareForm(sql, "PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
+        QueryPrepareHandle.class);
+    getPreparedQuery(handle);
+    return handle;
   }
 
   /**
@@ -153,9 +149,8 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query plan
-   * @throws LensAPIException
    */
-  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
+  public QueryPlan explainAndPrepare(String sql, String queryName) {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -164,15 +159,10 @@ public class LensStatement {
 
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    Response response = target.request().post(
-        Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
-        Response.class);
-    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
-      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
-    }
-
-    throw new LensAPIException(response.readEntity(LensAPIResult.class));
-
+    QueryPlan plan = target.request().post(
+      Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
+      QueryPlan.class);
+    return plan;
   }
 
   /**
@@ -351,11 +341,10 @@ public class LensStatement {
    *
    * @param sql the sql
    * @return the query plan
-   * @throws LensAPIException
    */
-  public LensAPIResult<QueryPlan> explainQuery(String sql) throws LensAPIException {
+  public QueryPlan explainQuery(String sql) {
     if (!connection.isOpen()) {
-      throw new IllegalStateException("Lens Connection has to be established before querying");
+      throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
 
     Client client = connection.buildClient();
@@ -367,13 +356,9 @@ public class LensStatement {
 
     WebTarget target = getQueryWebTarget(client);
 
-    Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
-
-    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
-      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
-    }
-
-    throw new LensAPIException(response.readEntity(LensAPIResult.class));
+    QueryPlan handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
+        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+    return handle;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
index 94badb9..dd3bb72 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
@@ -35,7 +35,7 @@ public class ColUnAvailableInTimeRangeException extends LensException {
 
   public ColUnAvailableInTimeRangeException(@NonNull final ColUnAvailableInTimeRange colUnAvailableInTimeRange) {
 
-    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo());
+    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue());
     this.colUnAvailableInTimeRange = colUnAvailableInTimeRange;
   }
 
@@ -52,8 +52,8 @@ public class ColUnAvailableInTimeRangeException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
-        errorMsg, stackTrace, colUnAvailableInTimeRange);
+    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(), errorMsg, stackTrace,
+        colUnAvailableInTimeRange);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
index bcd42dc..65b96d7 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
@@ -37,7 +37,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
 
   public FieldsCannotBeQueriedTogetherException(@NonNull final ConflictingFields conflictingFields) {
 
-    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo());
+    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue());
     this.conflictingFields = conflictingFields;
   }
 
@@ -52,7 +52,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo().getErrorCode(),
-        errorMsg, stackTrace, conflictingFields);
+    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue(), errorMsg, stackTrace,
+        conflictingFields);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
index 73a584f..1fe74e2 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
@@ -18,50 +18,46 @@
  */
 package org.apache.lens.cube.error;
 
-import org.apache.lens.server.api.LensErrorInfo;
-
 public enum LensCubeErrorCode {
-  // Error codes same for drivers
-  SYNTAX_ERROR(3001, 0),
-  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3002, 0),
-  MORE_THAN_ONE_CUBE(3003, 0),
-  NEITHER_CUBE_NOR_DIMENSION(3004, 0),
-  NO_TIMERANGE_FILTER(3005, 0),
-  NOT_A_TIMED_DIMENSION(3006, 0),
-  WRONG_TIME_RANGE_FORMAT(3007, 0),
-  NULL_DATE_VALUE(3008, 0),
-  INVALID_TIME_UNIT(3009, 0),
-  ALL_COLUMNS_NOT_SUPPORTED(3010, 0),
-  AMBIGOUS_DIM_COLUMN(3011, 0),
-  AMBIGOUS_CUBE_COLUMN(3012, 0),
-  NOT_A_CUBE_COLUMN(3013, 0),
-  INVALID_TIME_RANGE(3014, 0),
-  FROM_AFTER_TO(3015, 0),
-  JOIN_TARGET_NOT_CUBE_TABLE(3016, 0),
-  // Error codes different for drivers
-  CANNOT_USE_TIMERANGE_WRITER(3017, 100),
-  NO_DEFAULT_AGGREGATE(3018, 200),
-  EXPRESSION_NOT_IN_ANY_FACT(3019, 300),
-  NO_JOIN_CONDITION_AVAIABLE(3020, 400),
-  NO_JOIN_PATH(3021, 500),
-  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3022, 600),
-  NO_DIM_HAS_COLUMN(3023, 700),
-  NO_FACT_HAS_COLUMN(3024, 800),
-  NO_REF_COL_AVAILABLE(3025, 900),
-  COLUMN_NOT_FOUND(3026, 1000),
-  NO_CANDIDATE_DIM_AVAILABLE(3027, 1100),
-  NO_CANDIDATE_FACT_AVAILABLE(3028, 1200),
-  NO_CANDIDATE_DIM_STORAGE_TABLES(3029, 1300),
-  NO_STORAGE_TABLE_AVAIABLE(3030, 1400);
 
-  public LensErrorInfo getLensErrorInfo() {
-    return this.errorInfo;
-  }
+  SYNTAX_ERROR(3001),
+  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3002),
+  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3003),
+  NO_REF_COL_AVAILABLE(3004),
+  MORE_THAN_ONE_CUBE(3005),
+  NEITHER_CUBE_NOR_DIMENSION(3006),
+  NO_TIMERANGE_FILTER(3007),
+  NOT_A_TIMED_DIMENSION(3008),
+  WRONG_TIME_RANGE_FORMAT(3009),
+  NULL_DATE_VALUE(3010),
+  INVALID_TIME_UNIT(3011),
+  ALL_COLUMNS_NOT_SUPPORTED(3012),
+  AMBIGOUS_DIM_COLUMN(3013),
+  AMBIGOUS_CUBE_COLUMN(3014),
+  COLUMN_NOT_FOUND(3015),
+  NOT_A_CUBE_COLUMN(3016),
+  NO_CANDIDATE_FACT_AVAILABLE(3017),
+  NO_JOIN_CONDITION_AVAIABLE(3018),
+  NO_STORAGE_TABLE_AVAIABLE(3019),
+  NO_DEFAULT_AGGREGATE(3020),
+  INVALID_TIME_RANGE(3021),
+  FROM_AFTER_TO(3022),
+  NO_JOIN_PATH(3023),
+  JOIN_TARGET_NOT_CUBE_TABLE(3024),
+  NO_FACT_HAS_COLUMN(3025),
+  NO_CANDIDATE_DIM_STORAGE_TABLES(3026),
+  NO_DIM_HAS_COLUMN(3027),
+  NO_CANDIDATE_DIM_AVAILABLE(3028),
+  CANNOT_USE_TIMERANGE_WRITER(3029),
+  EXPRESSION_NOT_IN_ANY_FACT(3030);
 
-  LensCubeErrorCode(final int code, final int weight) {
-    this.errorInfo = new LensErrorInfo(code, weight, name());
+  public int getValue() {
+    return this.errorCode;
   }
 
-  private final LensErrorInfo errorInfo;
+  LensCubeErrorCode(final int code) {
+    this.errorCode = code;
+  }
 
+  private final int errorCode;
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
index b544a67..9c0f936 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
@@ -188,7 +188,7 @@ class AggregateResolver implements ContextRewriter {
         String aggregateFn = measure.getAggregate();
 
         if (StringUtils.isBlank(aggregateFn)) {
-          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getLensErrorInfo(), colname);
+          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getValue(), colname);
         }
         ASTNode fnroot = new ASTNode(new CommonToken(HiveParser.TOK_FUNCTION));
         fnroot.setParent(node.getParent());

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
index 0656049..98e38d5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
@@ -145,21 +145,20 @@ class AliasReplacer implements ContextRewriter {
           if (!inCube) {
             String prevDim = colToTableAlias.get(col.toLowerCase());
             if (prevDim != null && !prevDim.equals(dim.getName())) {
-              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo(),
-                  col, prevDim, dim.getName());
+              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue(), col, prevDim, dim.getName());
             }
             String dimAlias = cubeql.getAliasForTableName(dim.getName());
             colToTableAlias.put(col.toLowerCase(), dimAlias);
             tqc.addColumnsQueried(dimAlias, col.toLowerCase());
           } else {
             // throw error because column is in both cube and dimension table
-            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo(), col,
+            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue(), col,
                 cubeql.getCube().getName(), dim.getName());
           }
         }
       }
       if (colToTableAlias.get(col.toLowerCase()) == null) {
-        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo(), col);
+        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getValue(), col);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
index bd19d4c..4bd7cc8 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
@@ -52,7 +52,7 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
       while (it.hasNext()) {
         FactPartition part = it.next();
         if (part.hasContainingPart()) {
-          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
+          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
               "Partition has containing part");
         }
         if (first == null) {
@@ -60,11 +60,11 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
         } else {
           // validate partcol, update period are same for both
           if (!first.getPartCol().equalsIgnoreCase(part.getPartCol())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
               "Part columns are different in partitions");
           }
           if (!first.getPeriod().equals(part.getPeriod())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
               "Partitions are in different update periods");
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
index f81f3d5..69fbcc5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
@@ -92,8 +92,8 @@ class CandidateTableResolver implements ContextRewriter {
       if (cubeql.getCube() != null) {
         List<CubeFactTable> factTables = cubeql.getMetastoreClient().getAllFacts(cubeql.getCube());
         if (factTables.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(),
-              cubeql.getCube().getName() + " does not have any facts");
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), cubeql.getCube().getName()
+            + " does not have any facts");
         }
         for (CubeFactTable fact : factTables) {
           CandidateFact cfact = new CandidateFact(fact, cubeql.getCube());
@@ -122,7 +122,7 @@ class CandidateTableResolver implements ContextRewriter {
       List<CubeDimensionTable> dimtables = cubeql.getMetastoreClient().getAllDimensionTables(dim);
       if (dimtables.isEmpty()) {
         if (!optional) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(),
             "Dimension tables do not exist");
         } else {
           log.info("Not considering optional dimension {}  as, No dimension tables exist", dim);
@@ -284,7 +284,7 @@ class CandidateTableResolver implements ContextRewriter {
       Set<String> dimExprs = new HashSet<String>(cubeql.getQueriedExprs());
       dimExprs.removeAll(cubeql.getQueriedExprsWithMeasures());
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
           (!queriedDimAttrs.isEmpty() ? queriedDimAttrs.toString() : "")
           +  (!dimExprs.isEmpty() ? dimExprs.toString() : ""));
       }
@@ -308,14 +308,14 @@ class CandidateTableResolver implements ContextRewriter {
         String msrString = (!queriedMsrs.isEmpty() ? queriedMsrs.toString() : "")
           + (!cubeql.getQueriedExprsWithMeasures().isEmpty() ? cubeql.getQueriedExprsWithMeasures().toString() : "");
         if (cfactset.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
         }
         cubeql.getCandidateFactSets().addAll(cfactset);
         cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCause.columnNotFound(queriedMsrs,
           cubeql.getQueriedExprsWithMeasures()));
 
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
         }
       }
     }
@@ -431,7 +431,7 @@ class CandidateTableResolver implements ContextRewriter {
           OptionalDimCtx optdim = cubeql.getOptionalDimensionMap().get(dim);
           if ((cubeql.getDimensions() != null && cubeql.getDimensions().contains(dim))
             || (optdim != null && optdim.isRequiredInJoinChain)) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
                 cubeql.getAutoJoinCtx().getAllJoinPathColumnsOfTable(dim).toString());
           } else {
             // remove it from optional tables
@@ -474,7 +474,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
       }
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
             colSet == null ? "NULL" : colSet.toString());
       }
     }
@@ -669,7 +669,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
 
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(), cubeql
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(), cubeql
             .getColumnsQueried(dim.getName()).toString());
         }
       }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
index b95595a..dfe0c32 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
@@ -55,7 +55,7 @@ class ColumnResolver implements ContextRewriter {
       if (star != null) {
         int starType = star.getToken().getType();
         if (TOK_FUNCTIONSTAR == starType || TOK_ALLCOLREF == starType) {
-          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getLensErrorInfo());
+          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getValue());
         }
       }
     }
@@ -70,7 +70,7 @@ class ColumnResolver implements ContextRewriter {
     for (String table : cubeql.getTblAliasToColumns().keySet()) {
       if (!CubeQueryContext.DEFAULT_TABLE.equalsIgnoreCase(table)) {
         if (!cubeql.addQueriedTable(table)) {
-          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
+          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
index 450d172..16429f0 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
@@ -224,7 +224,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addJoinChain(alias, false);
       if (!added) {
         log.info("Queried tables do not exist. Missing table:{}", alias);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
       }
     }
   }
@@ -259,7 +259,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addQueriedTable(alias, destTable, isOptional, true);
       if (!added) {
         log.info("Queried tables do not exist. Missing tables:{}", destTable);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
       }
       log.info("Added join chain for {}", destTable);
       return true;
@@ -308,7 +308,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       if (metastoreClient.isCube(tblName)) {
         if (cube != null) {
           if (!cube.getName().equalsIgnoreCase(tblName)) {
-            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getLensErrorInfo(), cube.getName(), tblName);
+            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getValue(), cube.getName(), tblName);
           }
         }
         cube = metastoreClient.getCube(tblName);
@@ -687,7 +687,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         fromString = fact.getStorageString(getAliasForTableName(cube.getName()));
       } else {
         if (dimensions.size() != 1) {
-          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
+          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
         }
         Dimension dim = dimensions.iterator().next();
         fromString = dimsToQuery.get(dim).getStorageString(getAliasForTableName(dim.getName()));
@@ -740,7 +740,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         dimsToQuery.get(cubeTbls.get(joiningTable)).setWhereClauseAdded();
       }
     } else {
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
     }
   }
 
@@ -804,8 +804,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
               }
             }
           }
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(),
-              dim.getName(), reason);
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(), reason);
         }
       }
     }
@@ -840,7 +839,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
             }
           }
         }
-        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(), reason);
+        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), reason);
       }
     }
     return facts;

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
index e0759b0..0dfd7da 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
@@ -193,7 +193,7 @@ public class CubeQueryRewriter {
       analyzer = new CubeSemanticAnalyzer(conf, hconf);
       analyzer.analyze(astnode, qlCtx);
     } catch (SemanticException e) {
-      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
     }
     CubeQueryContext ctx = new CubeQueryContext(astnode, analyzer.getCubeQB(), conf, hconf);
     rewrite(rewriters, ctx);
@@ -210,7 +210,7 @@ public class CubeQueryRewriter {
       tree = pd.parse(command, qlCtx, false);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
     }
     return rewrite(tree);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
index cbcc76c..90ea63c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
@@ -156,13 +156,13 @@ public final class DateUtil {
       return ABSDATE_PARSER.get().parse(getAbsDateFormatString(str));
     } catch (ParseException e) {
       log.error("Invalid date format. expected only {} date provided:{}", ABSDATE_FMT, str, e);
-      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getLensErrorInfo(), ABSDATE_FMT, str);
+      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getValue(), ABSDATE_FMT, str);
     }
   }
 
   public static Date resolveRelativeDate(String str, Date now) throws LensException {
     if (StringUtils.isBlank(str)) {
-      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getLensErrorInfo());
+      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getValue());
     }
 
     // Resolve NOW with proper granularity

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
index a576f3a..3ef9652 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
@@ -251,7 +251,7 @@ public class DenormalizationResolver implements ContextRewriter {
               }
             }
             if (refered.references.isEmpty()) {
-              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getLensErrorInfo(), refered);
+              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getValue(), refered);
             }
             PickedReference picked = new PickedReference(refered.references.iterator().next(),
               cubeql.getAliasForTableName(refered.srcTable.getName()), tbl);
@@ -400,7 +400,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
               cubeql.getColumnsQueried(cubeql.getCube().getName()).toString());
         }
         cubeql.pruneCandidateFactSet(CandidateTablePruneCode.COLUMN_NOT_FOUND);
@@ -422,7 +422,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
 
           if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(),
               dim.toString(), cubeql.getColumnsQueried(dim.getName()).toString());
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
index 1964e32..586629f 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
@@ -148,7 +148,7 @@ public final class HQLParser {
       tree = driver.parse(query, ctx);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
     } catch (IOException e) {
       throw new RuntimeException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
index c7f1e2a..826a59d 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
@@ -847,8 +847,7 @@ class JoinResolver implements ContextRewriter {
       }
 
       if (minCostClause == null) {
-        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
-            qdims.toString(), autoJoinTarget.getName());
+        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), qdims.toString(), autoJoinTarget.getName());
       }
 
       log.info("Fact: {} minCostClause:{}", fact, minCostClause);
@@ -878,7 +877,7 @@ class JoinResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
             minCostClause.chainColumns.get(dim).toString());
         }
       }
@@ -1053,8 +1052,7 @@ class JoinResolver implements ContextRewriter {
           }
           log.warn("No join path between {} and {}", joinee.getName(), target.getName());
           if (cubeql.getDimensions().contains(joinee)) {
-            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
-                joinee.getName(), target.getName());
+            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), joinee.getName(), target.getName());
           } else {
             // if joinee is optional dim table, remove those candidate facts
             Set<CandidateTable> candidates = cubeql.getOptionalDimensionMap().get(joinee).requiredForCandidates;
@@ -1138,7 +1136,7 @@ class JoinResolver implements ContextRewriter {
     } else if (metastore.isCube(targetTableName)) {
       target = (AbstractCubeTable) metastore.getCube(targetTableName);
     } else {
-      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getLensErrorInfo(), targetTableName);
+      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getValue(), targetTableName);
     }
   }
 
@@ -1292,7 +1290,7 @@ class JoinResolver implements ContextRewriter {
       cubeql.setJoinCond(joinTree, HQLParser.getString(joinCond));
     } else {
       // No join condition specified. this should be an error
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
     }
     return joinTree;
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
index 2fcea8b..d8515d8 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
@@ -93,7 +93,7 @@ class MultiFactHQLContext extends SimpleHQLContext {
     StringBuilder select = new StringBuilder();
     for (int i = 0; i < query.getSelectAST().getChildCount(); i++) {
       if (selectToFactIndex.get(i) == null) {
-        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo(),
+        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue(),
             HQLParser.getString((ASTNode) query.getSelectAST().getChild(i)));
       }
       if (selectToFactIndex.get(i).size() == 1) {

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
index 7be7ace..b02499e 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
@@ -106,12 +106,11 @@ public class TimeRange {
 
   public void validate() throws LensException {
     if (partitionColumn == null || fromDate == null || toDate == null || fromDate.equals(toDate)) {
-      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo());
+      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
     }
 
     if (fromDate.after(toDate)) {
-      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo(),
-          fromDate.toString(), toDate.toString());
+      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getValue(), fromDate.toString(), toDate.toString());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
index 8a84249..fb1c89e 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
@@ -67,7 +67,7 @@ class TimerangeResolver implements ContextRewriter {
     // TOK_WHERE.TOK_FUNCTION.Identifier Or, it should be right hand child of
     // AND condition TOK_WHERE.KW_AND.TOK_FUNCTION.Identifier
     if (cubeql.getWhereAST() == null || cubeql.getWhereAST().getChildCount() < 1) {
-      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getLensErrorInfo());
+      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getValue());
     }
     searchTimeRanges(cubeql.getWhereAST(), cubeql, null, 0);
   }
@@ -112,7 +112,7 @@ class TimerangeResolver implements ContextRewriter {
     String timeDimName = getColumnName((ASTNode) timenode.getChild(1));
 
     if (!cubeql.getCube().getTimedDimensions().contains(timeDimName)) {
-      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getLensErrorInfo(), timeDimName);
+      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getValue(), timeDimName);
     }
     // Replace timeDimName with column which is used for partitioning. Assume
     // the same column
@@ -155,7 +155,7 @@ class TimerangeResolver implements ContextRewriter {
       for (TimeRange range : cubeql.getTimeRanges()) {
         if (column == null) {
           if (!cubeql.getCube().getTimedDimensions().contains(col)) {
-            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getLensErrorInfo(), col);
+            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getValue(), col);
           }
           continue;
         }
@@ -213,7 +213,7 @@ class TimerangeResolver implements ContextRewriter {
                 joinPathIterator.remove();
                 if (joinPaths.isEmpty()) {
                   // This dimension doesn't have any paths left
-                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
+                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(),
                       "No valid join path available for dimension " + dimension + " which would satisfy time range "
                           + range.getFromDate() + "-" + range.getToDate());
                 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
index 0f76c76..9120a70 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
@@ -69,12 +69,12 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
 
     e = getLensExceptionInRewrite("select msr11 + msr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo().getErrorCode());
+        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue());
     // no fact has the all the dimensions queried
     e = getLensExceptionInRewrite("select dim1, test_time_dim, msr3, msr13 from basecube where "
       + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
     String regexp = String.format(CandidateTablePruneCause.CandidateTablePruneCode.COLUMN_NOT_FOUND.errorFormat,
       "Column Sets: (.*?)", "queriable together");

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
index 7e5184c..b34c217 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
@@ -74,7 +74,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
   public void testQueryWithNow() throws Exception {
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube where" + " time_range_in(d_time, 'NOW - 2DAYS', 'NOW')", getConf());
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
   }
 
   @Test
@@ -118,19 +118,19 @@ public class TestCubeRewriter extends TestQueryRewrite {
     String qFrom4DaysBackDate = qFmt.format(from4DaysBackDate);
     LensException th = getLensExceptionInRewrite("select SUM(msr15) from testCube where"
       + " time_range_in(d_time, '"+ qFrom4DaysBackDate + "', '" + qTo + "')", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
   }
 
   @Test
   public void testCandidateTables() throws Exception {
     LensException th = getLensExceptionInRewrite(
       "select dim12, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
 
     // this query should through exception because invalidMsr is invalid
     th = getLensExceptionInRewrite(
       "SELECT cityid, invalidMsr from testCube " + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
   }
 
   @Test
@@ -187,7 +187,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(th);
     int endIndex = MISSING_PARTITIONS.errorFormat.length() - 3;
     assertEquals(
@@ -212,7 +212,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr4) from derivedCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
 
     // test join
     Configuration conf = getConf();
@@ -630,7 +630,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
     LensException th = getLensExceptionInRewrite(
       "select name, SUM(msr2) from testCube" + " join citydim" + " where " + TWO_DAYS_RANGE
         + " group by name", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
   }
 
   @Test
@@ -979,7 +979,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_MONTHS_RANGE_UPTO_HOURS, conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
 
     assertEquals(
@@ -1027,7 +1027,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     // state table is present on c1 with partition dumps and partitions added
     LensException e = getLensExceptionInRewrite("select name, capital from statedim ", conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue());
     assertEquals(extractPruneCause(e), new PruneCauses.BriefAndDetailedError(
       NO_CANDIDATE_STORAGES.errorFormat,
       new HashMap<String, List<CandidateTablePruneCause>>() {
@@ -1168,13 +1168,13 @@ public class TestCubeRewriter extends TestQueryRewrite {
         + TWO_DAYS_RANGE;
 
     LensException th = getLensExceptionInRewrite(query, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue());
 
     String q2 =
       "SELECT ambigdim2 from citydim join" + " statedim on citydim.stateid = statedim.id join countrydim on"
         + " statedim.countryid = countrydim.id";
     th = getLensExceptionInRewrite(q2, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo().getErrorCode());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue());
   }
 
   @Test
@@ -1467,7 +1467,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("TestJoinPathTimeRange: " + context.toHQL());
       fail("Expected query to fail because of invalid column life");
     } catch (LensException exc) {
-      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo().getErrorCode());
+      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getValue());
     } finally {
       // Add old column back
       cube.alterDimension(col);

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
index 493b8d6..ca07a0d 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
@@ -52,7 +52,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testColumnErrors() throws Exception {
     LensException th;
     th = getLensExceptionInRewrite("select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
 
     Assert.assertTrue(getLensExceptionErrorMessageInRewrite(
         "select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf).contains("nonexist"));
@@ -62,7 +62,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
 
     th = getLensExceptionInRewrite("select invalidexpr, " + "SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE,
         conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
   }
 
   @Test
@@ -337,7 +337,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testDerivedCube() throws ParseException, LensException, HiveException {
     LensException th =
       getLensExceptionInRewrite("select avgmsr from derivedCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
index cb63fad..6150b14 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
@@ -746,10 +746,10 @@ public class TestJoinResolver extends TestQueryRewrite {
   public void testUnreachableDim() throws ParseException, LensException, HiveException {
     LensException e1 = getLensExceptionInRewrite("select urdimid from testdim2", hconf);
     assertNotNull(e1);
-    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo().getErrorCode());
+    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue());
 
     LensException e2 = getLensExceptionInRewrite("select urdimid from testcube where " + TWO_DAYS_RANGE, hconf);
     assertNotNull(e2);
-    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
+    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
index a431717..3c3aa9c 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
@@ -68,7 +68,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo().getErrorCode());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getValue());
     }
   }
 
@@ -81,7 +81,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo().getErrorCode());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
index 0248409..e5540d2 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
@@ -68,8 +68,7 @@ public abstract class TestTimeRangeWriter {
     if (failDisjoint()) {
       Assert.assertNotNull(th);
       Assert
-        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.
-            getLensErrorInfo().getErrorCode());
+        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
     } else {
       Assert.assertNull(th);
       validateDisjoint(whereClause, null);

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
index 7bd7b6b..2083ef9 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
@@ -87,7 +87,7 @@ public class TestTimeRangeWriterWithQuery extends TestQueryRewrite {
     if (!CubeTestSetup.isZerothHour()) {
       Assert.assertNotNull(th);
       Assert
-      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo().getErrorCode());
+      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
     }
     // hourly partitions for two days
     conf.setBoolean(CubeQueryConfUtil.FAIL_QUERY_ON_PARTIAL_DATA, true);

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
index 9dc9773..c2254f1 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
@@ -18,7 +18,6 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
-import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
 import lombok.NonNull;
@@ -43,21 +42,21 @@ public class ESClientException extends LensException {
     super(cause);
   }
 
-  public ESClientException(LensErrorInfo errorInfo) {
-    super(errorInfo);
+  public ESClientException(int errorCode) {
+    super(errorCode);
   }
 
-  public ESClientException(String errorMsg, LensErrorInfo errorInfo) {
-    super(errorMsg, errorInfo);
+  public ESClientException(String errorMsg, int errorCode) {
+    super(errorMsg, errorCode);
   }
 
-  public ESClientException(LensErrorInfo errorInfo, Throwable cause,
+  public ESClientException(int errorCode, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorInfo, cause, errorMsgFormattingArgs);
+    super(errorCode, cause, errorMsgFormattingArgs);
   }
 
-  public ESClientException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
+  public ESClientException(String errorMsg, int errorcode, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
index 20634af..8127cba 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
@@ -18,10 +18,8 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
-import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
-
 import lombok.NonNull;
 
 public class InvalidQueryException extends LensException {
@@ -42,22 +40,22 @@ public class InvalidQueryException extends LensException {
     super(cause);
   }
 
-  public InvalidQueryException(LensErrorInfo errorInfo) {
-    super(errorInfo);
+  public InvalidQueryException(int errorCode) {
+    super(errorCode);
   }
 
-  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo) {
-    super(errorMsg, errorInfo);
+  public InvalidQueryException(String errorMsg, int errorCode) {
+    super(errorMsg, errorCode);
   }
 
-  public InvalidQueryException(LensErrorInfo errorInfo, Throwable cause,
+  public InvalidQueryException(int errorCode, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorInfo, cause, errorMsgFormattingArgs);
+    super(errorCode, cause, errorMsgFormattingArgs);
   }
 
-  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
+  public InvalidQueryException(String errorMsg, int errorcode, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
   }
 
   public InvalidQueryException(String s, Exception e) {

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
deleted file mode 100644
index 449120d..0000000
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.lens.server.api;
-
-import lombok.*;
-
-@AllArgsConstructor
-public class LensErrorInfo {
-
-  @Getter
-  private int errorCode;
-  @Getter
-  private int errorWeight;
-  @Getter
-  private String errorName;
-
-}

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
index 2036dce..c3ec099 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
@@ -305,6 +305,6 @@ public abstract class DriverQueryPlan {
   public QueryPlan toQueryPlan() throws UnsupportedEncodingException {
     return new QueryPlan(new ArrayList<>(tablesQueried), hasSubQuery, execMode != null ? execMode.name() : null,
       scanMode != null ? scanMode.name() : null, handle,
-      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build());
+      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build(), false, null);
   }
 }


[11/50] [abbrv] lens git commit: LENS-737 : Throw single error out with LensMultiException

Posted by ra...@apache.org.
LENS-737 : Throw single error out with LensMultiException


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/309a7ed5
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/309a7ed5
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/309a7ed5

Branch: refs/heads/current-release-line
Commit: 309a7ed5ddb3f3848ad0efca59b3177beba60dd2
Parents: ea8bc91
Author: Sushil Mohanty <su...@inmobi.com>
Authored: Tue Sep 8 09:45:58 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Tue Sep 8 09:45:58 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryPlan.java    |  24 --
 lens-api/src/main/resources/lens-errors.conf    | 325 +++++++++----------
 .../lens/cli/commands/LensQueryCommands.java    |  83 +++--
 .../apache/lens/cli/ExecuteQueryCommandIT.java  |   4 +-
 .../apache/lens/cli/TestLensQueryCommands.java  |   8 +-
 .../java/org/apache/lens/client/LensClient.java |   6 +-
 .../org/apache/lens/client/LensStatement.java   |  47 ++-
 .../ColUnAvailableInTimeRangeException.java     |   6 +-
 .../FieldsCannotBeQueriedTogetherException.java |   6 +-
 .../lens/cube/error/LensCubeErrorCode.java      |  76 +++--
 .../lens/cube/parse/AggregateResolver.java      |   2 +-
 .../apache/lens/cube/parse/AliasReplacer.java   |   7 +-
 .../lens/cube/parse/BetweenTimeRangeWriter.java |   6 +-
 .../lens/cube/parse/CandidateTableResolver.java |  18 +-
 .../apache/lens/cube/parse/ColumnResolver.java  |   4 +-
 .../lens/cube/parse/CubeQueryContext.java       |  15 +-
 .../lens/cube/parse/CubeQueryRewriter.java      |   4 +-
 .../org/apache/lens/cube/parse/DateUtil.java    |   4 +-
 .../cube/parse/DenormalizationResolver.java     |   6 +-
 .../org/apache/lens/cube/parse/HQLParser.java   |   2 +-
 .../apache/lens/cube/parse/JoinResolver.java    |  12 +-
 .../lens/cube/parse/MultiFactHQLContext.java    |   2 +-
 .../org/apache/lens/cube/parse/TimeRange.java   |   5 +-
 .../lens/cube/parse/TimerangeResolver.java      |   8 +-
 .../lens/cube/parse/TestBaseCubeQueries.java    |   4 +-
 .../lens/cube/parse/TestCubeRewriter.java       |  24 +-
 .../lens/cube/parse/TestExpressionResolver.java |   6 +-
 .../lens/cube/parse/TestJoinResolver.java       |   4 +-
 .../lens/cube/parse/TestTimeRangeExtractor.java |   4 +-
 .../lens/cube/parse/TestTimeRangeWriter.java    |   3 +-
 .../parse/TestTimeRangeWriterWithQuery.java     |   2 +-
 .../driver/es/exceptions/ESClientException.java |  17 +-
 .../es/exceptions/InvalidQueryException.java    |  18 +-
 .../apache/lens/server/api/LensErrorInfo.java   |  34 ++
 .../lens/server/api/driver/DriverQueryPlan.java |   2 +-
 .../lens/server/api/error/LensException.java    | 102 ++++--
 .../api/error/LensMultiCauseException.java      |  20 +-
 .../lens/server/error/LensServerErrorCode.java  |  18 +-
 .../UnSupportedQuerySubmitOpException.java      |   4 +-
 .../server/query/QueryExecutionServiceImpl.java |  29 +-
 .../lens/server/query/QueryServiceResource.java |  33 +-
 .../common/ErrorResponseExpectedData.java       |   2 +-
 .../lens/server/common/FailingQueryDriver.java  |   2 +-
 .../server/query/QueryAPIErrorResponseTest.java |  22 +-
 .../lens/server/query/TestQueryService.java     |  50 ++-
 45 files changed, 585 insertions(+), 495 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
index 164195b..c46972d 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
@@ -114,32 +114,8 @@ public class QueryPlan extends QuerySubmitResult {
   @Getter
   private QueryCostTO queryCost;
 
-  /**
-   * The error.
-   */
-  @XmlElement
-  @Getter
-  private boolean error = false;
-
-  /**
-   * The error msg.
-   */
-  @XmlElement
-  @Getter
-  private String errorMsg;
-
   public String getPlanString() throws UnsupportedEncodingException {
     return URLDecoder.decode(planString, "UTF-8");
   }
 
-  /**
-   * Instantiates a new query plan.
-   *
-   * @param hasError the has error
-   * @param errorMsg the error msg
-   */
-  public QueryPlan(boolean hasError, String errorMsg) {
-    this.error = hasError;
-    this.errorMsg = errorMsg;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-api/src/main/resources/lens-errors.conf
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/lens-errors.conf b/lens-api/src/main/resources/lens-errors.conf
index 3fb191e..5428041 100644
--- a/lens-api/src/main/resources/lens-errors.conf
+++ b/lens-api/src/main/resources/lens-errors.conf
@@ -83,179 +83,178 @@ lensCubeErrors = [
   {
     errorCode = 3002
     httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s. Please remove conflicting fields and try again."
+    payloadClass = org.apache.lens.cube.error.ConflictingFields
+  }
+
+  {
+    errorCode = 3003
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "More than one cube accessed in query : %s and %s"
+  }
+
+  {
+    errorCode = 3004
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Neither cube nor dimensions accessed in the query"
+  }
+
+  {
+    errorCode = 3005
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No timerange filter specified"
+  }
+
+  {
+    errorCode = 3006
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s is not timed dimension"
+  }
+
+  {
+    errorCode = 3007
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
+  }
+
+  {
+    errorCode = 3008
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Date value cannot be null or empty"
+  }
+
+  {
+    errorCode = 3009
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Invalid time unit %s"
+  }
+
+  {
+    errorCode = 3010
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Selecting all columns is not supported"
+  }
+
+  {
+    errorCode = 3011
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Ambiguous column %s, in dimensions %s and %s"
+  }
+
+  {
+    errorCode = 3012
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
+  }
+
+  {
+    errorCode = 3013
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s : Not a cube column"
+  }
+
+  {
+    errorCode = 3014
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Invalid time range"
+  }
+
+  {
+    errorCode = 3015
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "From date: %s  should be smaller than to date: %s"
+  }
+
+  {
+    errorCode = 3016
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Join target table: %s is neither dimension nor cube"
+  }
+
+  {
+    errorCode = 3017
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Configured timerange writer cannot be used. Reason %s"
+  }
+
+  {
+    errorCode = 3018
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No join condition available"
+  }
+
+  {
+    errorCode = 3019
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Expression %s is not available in any fact"
+  }
+
+  {
+    errorCode = 3020
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Default aggregate is not set for measure: %s"
+  }
+
+  {
+    errorCode = 3021
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No join path defined from %s to %s"
+  }
+
+  {
+    errorCode = 3022
+    httpStatusCode = ${BAD_REQUEST}
     errorMsg = "%s can only be queried %s. Please adjust the selected time range accordingly."
     payloadClass = org.apache.lens.cube.error.ColUnAvailableInTimeRange
   }
 
   {
-    errorCode = 3003
+    errorCode = 3023
     httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "%s. Please remove conflicting fields and try again."
-    payloadClass = org.apache.lens.cube.error.ConflictingFields
+    errorMsg = "No dimension table has the queried columns for %s, columns: %s"
+  }
+
+  {
+    errorCode = 3024
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No fact table has the queried columns : %s"
+  }
+
+  {
+    errorCode = 3025
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No reference column available for : %s "
   }
 
   {
-   errorCode = 3004
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No reference column available for : %s "
-  }
-
- {
-   errorCode = 3005
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "More than one cube accessed in query : %s and %s"
- }
-
- {
-   errorCode = 3006
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Neither cube nor dimensions accessed in the query"
- }
-
- {
-   errorCode = 3007
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No timerange filter specified"
- }
-
- {
-   errorCode = 3008
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "%s is not timed dimension"
- }
-
- {
-   errorCode = 3009
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
- }
-
- {
-   errorCode = 3010
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Date value cannot be null or empty"
- }
-
- {
-   errorCode = 3011
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Invalid time unit %s"
- }
-
- {
-   errorCode = 3012
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Selecting all columns is not supported"
- }
-
- {
-   errorCode = 3013
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Ambiguous column %s, in dimensions %s and %s"
- }
-
- {
-   errorCode = 3014
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
- }
-
- {
-   errorCode = 3015
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Could not find the table containing column: %s"
- }
-
- {
-   errorCode = 3016
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "%s : Not a cube column"
- }
-
- {
-   errorCode = 3017
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate fact table available to answer the query, because %s"
- }
-
- {
-   errorCode = 3018
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No join condition available"
- }
-
- {
-   errorCode = 3019
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No storage table available for candidate fact: %s"
- }
-
- {
-   errorCode = 3020
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Default aggregate is not set for measure: %s"
- }
-
- {
-   errorCode = 3021
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Invalid time range"
- }
-
- {
-   errorCode = 3022
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "From date: %s  should be smaller than to date: %s"
- }
-
- {
-   errorCode = 3023
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No join path defined from %s to %s"
- }
-
- {
-   errorCode = 3024
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Join target table: %s is neither dimension nor cube"
- }
-
- {
-   errorCode = 3025
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No fact table has the queried columns : %s"
- }
-
- {
-   errorCode = 3026
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate dimension storage tables for dimension because %s"
- }
-
- {
-   errorCode = 3027
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No dimension table has the queried columns for %s, columns: %s"
- }
-
- {
-   errorCode = 3028
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
- }
-
- {
-   errorCode = 3029
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Configured timerange writer cannot be used. Reason %s"
- }
-
- {
-   errorCode = 3030
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Expression %s is not available in any fact"
- }
+    errorCode = 3026
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Could not find the table containing column: %s"
+  }
 
+  {
+    errorCode = 3027
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
+  }
+
+  {
+    errorCode = 3028
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate fact table available to answer the query, because %s"
+  }
+
+  {
+    errorCode = 3029
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate dimension storage tables for dimension because %s"
+  }
+
+  {
+    errorCode = 3030
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No storage table available for candidate fact: %s"
+  }
 ]
 
 # Overriding errors in lens-errors.conf via lens-errors-override.conf:

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 7a5b177..44c0c62 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -206,26 +206,34 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param sql      the sql
    * @param location the location
    * @return the string
+   * @throws LensAPIException
    * @throws UnsupportedEncodingException the unsupported encoding exception
    */
-  @CliCommand(value = "query explain",
-    help = "Explain execution plan of query <query-string>. Can optionally save the plan"
-      + " to a file by providing <save_location>")
-  public String explainQuery(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
-    @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") final File path)
-    throws IOException {
-    QueryPlan plan = getClient().getQueryPlan(sql);
-    if (plan.isError()) {
-      return "Explain FAILED:" + plan.getErrorMsg();
-    }
-    if (path != null && StringUtils.isNotBlank(path.getPath())) {
-      String validPath = getValidPath(path, false, false);
-      try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath), Charset.defaultCharset())) {
-        osw.write(plan.getPlanString());
+  @CliCommand(value = "query explain", help = "Explain execution plan of query <query-string>. "
+      + "Can optionally save the plan to a file by providing <save_location>")
+  public String explainQuery(@CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
+      @CliOption(key = { "save_location" }, mandatory = false, help = "<save_location>") final File path)
+    throws IOException, LensAPIException {
+    PrettyPrintable cliOutput;
+
+    try {
+      QueryPlan plan = getClient().getQueryPlan(sql).getData();
+      if (path != null && StringUtils.isNotBlank(path.getPath())) {
+        String validPath = getValidPath(path, false, false);
+        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath),
+            Charset.defaultCharset())) {
+          osw.write(plan.getPlanString());
+        }
+        return "Saved to " + validPath;
       }
-      return "Saved to " + validPath;
+      return plan.getPlanString();
+    } catch (final LensAPIException e) {
+      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
+      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
+    } catch (final LensBriefErrorException e) {
+      cliOutput = e.getIdBriefErrorTemplate();
     }
-    return plan.getPlanString();
+    return cliOutput.toPrettyString();
   }
 
   /**
@@ -446,36 +454,47 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param queryName the query name
    * @return the string
    * @throws UnsupportedEncodingException the unsupported encoding exception
+   * @throws LensAPIException
    */
   @CliCommand(value = "prepQuery prepare",
     help = "Prepapre query <query-string> and return prepare handle. Can optionaly provide <query-name>")
   public String prepare(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
     @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException {
-    return getClient().prepare(sql, queryName).toString();
+    throws UnsupportedEncodingException, LensAPIException {
+    return getClient().prepare(sql, queryName).getData().toString();
   }
 
   /**
    * Explain and prepare.
    *
-   * @param sql       the sql
-   * @param queryName the query name
+   * @param sql
+   *          the sql
+   * @param queryName
+   *          the query name
    * @return the string
-   * @throws UnsupportedEncodingException the unsupported encoding exception
+   * @throws UnsupportedEncodingException
+   *           the unsupported encoding exception
+   * @throws LensAPIException
    */
-  @CliCommand(value = "prepQuery explain",
-    help = "Explain and prepare query <query-string>. Can optionally provide <query-name>")
+  @CliCommand(value = "prepQuery explain", help = "Explain and prepare query <query-string>. "
+      + "Can optionally provide <query-name>")
   public String explainAndPrepare(
-    @CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
-    @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException {
 
-    QueryPlan plan = getClient().explainAndPrepare(sql, queryName);
-    if (plan.isError()) {
-      return "Explain FAILED:" + plan.getErrorMsg();
+  @CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
+      @CliOption(key = { "name" }, mandatory = false, help = "<query-name>") String queryName)
+    throws UnsupportedEncodingException, LensAPIException {
+    PrettyPrintable cliOutput;
+    try {
+      QueryPlan plan = getClient().explainAndPrepare(sql, queryName).getData();
+      StringBuilder planStr = new StringBuilder(plan.getPlanString());
+      planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
+      return planStr.toString();
+    } catch (final LensAPIException e) {
+      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
+      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
+    } catch (final LensBriefErrorException e) {
+      cliOutput = e.getIdBriefErrorTemplate();
     }
-    StringBuilder planStr = new StringBuilder(plan.getPlanString());
-    planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
-    return planStr.toString();
+    return cliOutput.toPrettyString();
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
index b3fcccb..7f8b091 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
@@ -23,11 +23,9 @@ import static org.testng.Assert.assertTrue;
 import org.apache.lens.cli.commands.LensQueryCommands;
 import org.apache.lens.client.LensClient;
 
-import org.testng.annotations.Test;
-
 public class ExecuteQueryCommandIT extends LensCliApplicationTest {
 
-  @Test
+ // @Test
   public void testExecuteSyncQueryWithSyntaxError() {
 
     LensQueryCommands lensQueryCommands = new LensQueryCommands();

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
index 7a437a1..308c036 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
@@ -83,11 +83,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    testExplainFailQuery(qCom);
+    //testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    testFailPreparedQuery(qCom);
+    //testFailPreparedQuery(qCom);
     // run all query commands with query metrics enabled.
     client = new LensClient();
     client.setConnectionParam("lens.query.enable.persistent.resultset.indriver", "false");
@@ -99,11 +99,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    testExplainFailQuery(qCom);
+    //testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    testFailPreparedQuery(qCom);
+    //testFailPreparedQuery(qCom);
   }
 
 

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-client/src/main/java/org/apache/lens/client/LensClient.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
index afc76e5..5fd04c4 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
@@ -207,7 +207,7 @@ public class LensClient {
     return getQueryDetails(QueryHandle.fromString(handle));
   }
 
-  public QueryPlan getQueryPlan(String q) {
+  public LensAPIResult<QueryPlan> getQueryPlan(String q) throws LensAPIException {
     return new LensStatement(connection).explainQuery(q);
   }
 
@@ -569,11 +569,11 @@ public class LensClient {
     return mc.updatePartitionsOfDimensionTable(table, storage, partsSpec);
   }
 
-  public QueryPrepareHandle prepare(String sql, String queryName) {
+  public LensAPIResult<QueryPrepareHandle> prepare(String sql, String queryName) throws LensAPIException {
     return statement.prepareQuery(sql, queryName);
   }
 
-  public QueryPlan explainAndPrepare(String sql, String queryName) {
+  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
     return statement.explainAndPrepare(sql, queryName);
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
index 397bd82..0a511f0 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
@@ -127,8 +127,9 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query prepare handle
+   * @throws LensAPIException
    */
-  public QueryPrepareHandle prepareQuery(String sql, String queryName) {
+  public LensAPIResult<QueryPrepareHandle> prepareQuery(String sql, String queryName) throws LensAPIException {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -136,11 +137,14 @@ public class LensStatement {
     Client client = connection.buildClient();
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    QueryPrepareHandle handle = target.request().post(
-        Entity.entity(prepareForm(sql, "PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
-        QueryPrepareHandle.class);
-    getPreparedQuery(handle);
-    return handle;
+    Response response = target.request().post(Entity.entity(prepareForm(sql, "PREPARE", queryName),
+        MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPrepareHandle>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
   }
 
   /**
@@ -149,8 +153,9 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query plan
+   * @throws LensAPIException
    */
-  public QueryPlan explainAndPrepare(String sql, String queryName) {
+  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -159,10 +164,15 @@ public class LensStatement {
 
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    QueryPlan plan = target.request().post(
-      Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
-    return plan;
+    Response response = target.request().post(
+        Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
+        Response.class);
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
+
   }
 
   /**
@@ -341,10 +351,11 @@ public class LensStatement {
    *
    * @param sql the sql
    * @return the query plan
+   * @throws LensAPIException
    */
-  public QueryPlan explainQuery(String sql) {
+  public LensAPIResult<QueryPlan> explainQuery(String sql) throws LensAPIException {
     if (!connection.isOpen()) {
-      throw new IllegalStateException("Lens Connection has to be " + "established before querying");
+      throw new IllegalStateException("Lens Connection has to be established before querying");
     }
 
     Client client = connection.buildClient();
@@ -356,9 +367,13 @@ public class LensStatement {
 
     WebTarget target = getQueryWebTarget(client);
 
-    QueryPlan handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
-    return handle;
+    Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
index dd3bb72..94badb9 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
@@ -35,7 +35,7 @@ public class ColUnAvailableInTimeRangeException extends LensException {
 
   public ColUnAvailableInTimeRangeException(@NonNull final ColUnAvailableInTimeRange colUnAvailableInTimeRange) {
 
-    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue());
+    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo());
     this.colUnAvailableInTimeRange = colUnAvailableInTimeRange;
   }
 
@@ -52,8 +52,8 @@ public class ColUnAvailableInTimeRangeException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(), errorMsg, stackTrace,
-        colUnAvailableInTimeRange);
+    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
+        errorMsg, stackTrace, colUnAvailableInTimeRange);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
index 65b96d7..bcd42dc 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
@@ -37,7 +37,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
 
   public FieldsCannotBeQueriedTogetherException(@NonNull final ConflictingFields conflictingFields) {
 
-    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue());
+    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo());
     this.conflictingFields = conflictingFields;
   }
 
@@ -52,7 +52,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue(), errorMsg, stackTrace,
-        conflictingFields);
+    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo().getErrorCode(),
+        errorMsg, stackTrace, conflictingFields);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
index 1fe74e2..73a584f 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
@@ -18,46 +18,50 @@
  */
 package org.apache.lens.cube.error;
 
-public enum LensCubeErrorCode {
+import org.apache.lens.server.api.LensErrorInfo;
 
-  SYNTAX_ERROR(3001),
-  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3002),
-  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3003),
-  NO_REF_COL_AVAILABLE(3004),
-  MORE_THAN_ONE_CUBE(3005),
-  NEITHER_CUBE_NOR_DIMENSION(3006),
-  NO_TIMERANGE_FILTER(3007),
-  NOT_A_TIMED_DIMENSION(3008),
-  WRONG_TIME_RANGE_FORMAT(3009),
-  NULL_DATE_VALUE(3010),
-  INVALID_TIME_UNIT(3011),
-  ALL_COLUMNS_NOT_SUPPORTED(3012),
-  AMBIGOUS_DIM_COLUMN(3013),
-  AMBIGOUS_CUBE_COLUMN(3014),
-  COLUMN_NOT_FOUND(3015),
-  NOT_A_CUBE_COLUMN(3016),
-  NO_CANDIDATE_FACT_AVAILABLE(3017),
-  NO_JOIN_CONDITION_AVAIABLE(3018),
-  NO_STORAGE_TABLE_AVAIABLE(3019),
-  NO_DEFAULT_AGGREGATE(3020),
-  INVALID_TIME_RANGE(3021),
-  FROM_AFTER_TO(3022),
-  NO_JOIN_PATH(3023),
-  JOIN_TARGET_NOT_CUBE_TABLE(3024),
-  NO_FACT_HAS_COLUMN(3025),
-  NO_CANDIDATE_DIM_STORAGE_TABLES(3026),
-  NO_DIM_HAS_COLUMN(3027),
-  NO_CANDIDATE_DIM_AVAILABLE(3028),
-  CANNOT_USE_TIMERANGE_WRITER(3029),
-  EXPRESSION_NOT_IN_ANY_FACT(3030);
+public enum LensCubeErrorCode {
+  // Error codes same for drivers
+  SYNTAX_ERROR(3001, 0),
+  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3002, 0),
+  MORE_THAN_ONE_CUBE(3003, 0),
+  NEITHER_CUBE_NOR_DIMENSION(3004, 0),
+  NO_TIMERANGE_FILTER(3005, 0),
+  NOT_A_TIMED_DIMENSION(3006, 0),
+  WRONG_TIME_RANGE_FORMAT(3007, 0),
+  NULL_DATE_VALUE(3008, 0),
+  INVALID_TIME_UNIT(3009, 0),
+  ALL_COLUMNS_NOT_SUPPORTED(3010, 0),
+  AMBIGOUS_DIM_COLUMN(3011, 0),
+  AMBIGOUS_CUBE_COLUMN(3012, 0),
+  NOT_A_CUBE_COLUMN(3013, 0),
+  INVALID_TIME_RANGE(3014, 0),
+  FROM_AFTER_TO(3015, 0),
+  JOIN_TARGET_NOT_CUBE_TABLE(3016, 0),
+  // Error codes different for drivers
+  CANNOT_USE_TIMERANGE_WRITER(3017, 100),
+  NO_DEFAULT_AGGREGATE(3018, 200),
+  EXPRESSION_NOT_IN_ANY_FACT(3019, 300),
+  NO_JOIN_CONDITION_AVAIABLE(3020, 400),
+  NO_JOIN_PATH(3021, 500),
+  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3022, 600),
+  NO_DIM_HAS_COLUMN(3023, 700),
+  NO_FACT_HAS_COLUMN(3024, 800),
+  NO_REF_COL_AVAILABLE(3025, 900),
+  COLUMN_NOT_FOUND(3026, 1000),
+  NO_CANDIDATE_DIM_AVAILABLE(3027, 1100),
+  NO_CANDIDATE_FACT_AVAILABLE(3028, 1200),
+  NO_CANDIDATE_DIM_STORAGE_TABLES(3029, 1300),
+  NO_STORAGE_TABLE_AVAIABLE(3030, 1400);
 
-  public int getValue() {
-    return this.errorCode;
+  public LensErrorInfo getLensErrorInfo() {
+    return this.errorInfo;
   }
 
-  LensCubeErrorCode(final int code) {
-    this.errorCode = code;
+  LensCubeErrorCode(final int code, final int weight) {
+    this.errorInfo = new LensErrorInfo(code, weight, name());
   }
 
-  private final int errorCode;
+  private final LensErrorInfo errorInfo;
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
index 9c0f936..b544a67 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
@@ -188,7 +188,7 @@ class AggregateResolver implements ContextRewriter {
         String aggregateFn = measure.getAggregate();
 
         if (StringUtils.isBlank(aggregateFn)) {
-          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getValue(), colname);
+          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getLensErrorInfo(), colname);
         }
         ASTNode fnroot = new ASTNode(new CommonToken(HiveParser.TOK_FUNCTION));
         fnroot.setParent(node.getParent());

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
index 98e38d5..0656049 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
@@ -145,20 +145,21 @@ class AliasReplacer implements ContextRewriter {
           if (!inCube) {
             String prevDim = colToTableAlias.get(col.toLowerCase());
             if (prevDim != null && !prevDim.equals(dim.getName())) {
-              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue(), col, prevDim, dim.getName());
+              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo(),
+                  col, prevDim, dim.getName());
             }
             String dimAlias = cubeql.getAliasForTableName(dim.getName());
             colToTableAlias.put(col.toLowerCase(), dimAlias);
             tqc.addColumnsQueried(dimAlias, col.toLowerCase());
           } else {
             // throw error because column is in both cube and dimension table
-            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue(), col,
+            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo(), col,
                 cubeql.getCube().getName(), dim.getName());
           }
         }
       }
       if (colToTableAlias.get(col.toLowerCase()) == null) {
-        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getValue(), col);
+        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo(), col);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
index 4bd7cc8..bd19d4c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
@@ -52,7 +52,7 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
       while (it.hasNext()) {
         FactPartition part = it.next();
         if (part.hasContainingPart()) {
-          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Partition has containing part");
         }
         if (first == null) {
@@ -60,11 +60,11 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
         } else {
           // validate partcol, update period are same for both
           if (!first.getPartCol().equalsIgnoreCase(part.getPartCol())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Part columns are different in partitions");
           }
           if (!first.getPeriod().equals(part.getPeriod())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Partitions are in different update periods");
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
index 69fbcc5..f81f3d5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
@@ -92,8 +92,8 @@ class CandidateTableResolver implements ContextRewriter {
       if (cubeql.getCube() != null) {
         List<CubeFactTable> factTables = cubeql.getMetastoreClient().getAllFacts(cubeql.getCube());
         if (factTables.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), cubeql.getCube().getName()
-            + " does not have any facts");
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(),
+              cubeql.getCube().getName() + " does not have any facts");
         }
         for (CubeFactTable fact : factTables) {
           CandidateFact cfact = new CandidateFact(fact, cubeql.getCube());
@@ -122,7 +122,7 @@ class CandidateTableResolver implements ContextRewriter {
       List<CubeDimensionTable> dimtables = cubeql.getMetastoreClient().getAllDimensionTables(dim);
       if (dimtables.isEmpty()) {
         if (!optional) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(), dim.getName(),
             "Dimension tables do not exist");
         } else {
           log.info("Not considering optional dimension {}  as, No dimension tables exist", dim);
@@ -284,7 +284,7 @@ class CandidateTableResolver implements ContextRewriter {
       Set<String> dimExprs = new HashSet<String>(cubeql.getQueriedExprs());
       dimExprs.removeAll(cubeql.getQueriedExprsWithMeasures());
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
           (!queriedDimAttrs.isEmpty() ? queriedDimAttrs.toString() : "")
           +  (!dimExprs.isEmpty() ? dimExprs.toString() : ""));
       }
@@ -308,14 +308,14 @@ class CandidateTableResolver implements ContextRewriter {
         String msrString = (!queriedMsrs.isEmpty() ? queriedMsrs.toString() : "")
           + (!cubeql.getQueriedExprsWithMeasures().isEmpty() ? cubeql.getQueriedExprsWithMeasures().toString() : "");
         if (cfactset.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
         }
         cubeql.getCandidateFactSets().addAll(cfactset);
         cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCause.columnNotFound(queriedMsrs,
           cubeql.getQueriedExprsWithMeasures()));
 
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
         }
       }
     }
@@ -431,7 +431,7 @@ class CandidateTableResolver implements ContextRewriter {
           OptionalDimCtx optdim = cubeql.getOptionalDimensionMap().get(dim);
           if ((cubeql.getDimensions() != null && cubeql.getDimensions().contains(dim))
             || (optdim != null && optdim.isRequiredInJoinChain)) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
                 cubeql.getAutoJoinCtx().getAllJoinPathColumnsOfTable(dim).toString());
           } else {
             // remove it from optional tables
@@ -474,7 +474,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
       }
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
             colSet == null ? "NULL" : colSet.toString());
       }
     }
@@ -669,7 +669,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
 
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(), cubeql
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(), cubeql
             .getColumnsQueried(dim.getName()).toString());
         }
       }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
index dfe0c32..b95595a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
@@ -55,7 +55,7 @@ class ColumnResolver implements ContextRewriter {
       if (star != null) {
         int starType = star.getToken().getType();
         if (TOK_FUNCTIONSTAR == starType || TOK_ALLCOLREF == starType) {
-          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getValue());
+          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getLensErrorInfo());
         }
       }
     }
@@ -70,7 +70,7 @@ class ColumnResolver implements ContextRewriter {
     for (String table : cubeql.getTblAliasToColumns().keySet()) {
       if (!CubeQueryContext.DEFAULT_TABLE.equalsIgnoreCase(table)) {
         if (!cubeql.addQueriedTable(table)) {
-          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
index 16429f0..450d172 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
@@ -224,7 +224,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addJoinChain(alias, false);
       if (!added) {
         log.info("Queried tables do not exist. Missing table:{}", alias);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
       }
     }
   }
@@ -259,7 +259,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addQueriedTable(alias, destTable, isOptional, true);
       if (!added) {
         log.info("Queried tables do not exist. Missing tables:{}", destTable);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
       }
       log.info("Added join chain for {}", destTable);
       return true;
@@ -308,7 +308,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       if (metastoreClient.isCube(tblName)) {
         if (cube != null) {
           if (!cube.getName().equalsIgnoreCase(tblName)) {
-            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getValue(), cube.getName(), tblName);
+            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getLensErrorInfo(), cube.getName(), tblName);
           }
         }
         cube = metastoreClient.getCube(tblName);
@@ -687,7 +687,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         fromString = fact.getStorageString(getAliasForTableName(cube.getName()));
       } else {
         if (dimensions.size() != 1) {
-          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
         }
         Dimension dim = dimensions.iterator().next();
         fromString = dimsToQuery.get(dim).getStorageString(getAliasForTableName(dim.getName()));
@@ -740,7 +740,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         dimsToQuery.get(cubeTbls.get(joiningTable)).setWhereClauseAdded();
       }
     } else {
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
     }
   }
 
@@ -804,7 +804,8 @@ public class CubeQueryContext implements TrackQueriedColumns {
               }
             }
           }
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(), reason);
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(),
+              dim.getName(), reason);
         }
       }
     }
@@ -839,7 +840,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
             }
           }
         }
-        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), reason);
+        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(), reason);
       }
     }
     return facts;

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
index 0dfd7da..e0759b0 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
@@ -193,7 +193,7 @@ public class CubeQueryRewriter {
       analyzer = new CubeSemanticAnalyzer(conf, hconf);
       analyzer.analyze(astnode, qlCtx);
     } catch (SemanticException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     }
     CubeQueryContext ctx = new CubeQueryContext(astnode, analyzer.getCubeQB(), conf, hconf);
     rewrite(rewriters, ctx);
@@ -210,7 +210,7 @@ public class CubeQueryRewriter {
       tree = pd.parse(command, qlCtx, false);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     }
     return rewrite(tree);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
index 90ea63c..cbcc76c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
@@ -156,13 +156,13 @@ public final class DateUtil {
       return ABSDATE_PARSER.get().parse(getAbsDateFormatString(str));
     } catch (ParseException e) {
       log.error("Invalid date format. expected only {} date provided:{}", ABSDATE_FMT, str, e);
-      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getValue(), ABSDATE_FMT, str);
+      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getLensErrorInfo(), ABSDATE_FMT, str);
     }
   }
 
   public static Date resolveRelativeDate(String str, Date now) throws LensException {
     if (StringUtils.isBlank(str)) {
-      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getValue());
+      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getLensErrorInfo());
     }
 
     // Resolve NOW with proper granularity

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
index 3ef9652..a576f3a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
@@ -251,7 +251,7 @@ public class DenormalizationResolver implements ContextRewriter {
               }
             }
             if (refered.references.isEmpty()) {
-              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getValue(), refered);
+              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getLensErrorInfo(), refered);
             }
             PickedReference picked = new PickedReference(refered.references.iterator().next(),
               cubeql.getAliasForTableName(refered.srcTable.getName()), tbl);
@@ -400,7 +400,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
               cubeql.getColumnsQueried(cubeql.getCube().getName()).toString());
         }
         cubeql.pruneCandidateFactSet(CandidateTablePruneCode.COLUMN_NOT_FOUND);
@@ -422,7 +422,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
 
           if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(),
               dim.toString(), cubeql.getColumnsQueried(dim.getName()).toString());
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
index 586629f..1964e32 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
@@ -148,7 +148,7 @@ public final class HQLParser {
       tree = driver.parse(query, ctx);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     } catch (IOException e) {
       throw new RuntimeException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
index 826a59d..c7f1e2a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
@@ -847,7 +847,8 @@ class JoinResolver implements ContextRewriter {
       }
 
       if (minCostClause == null) {
-        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), qdims.toString(), autoJoinTarget.getName());
+        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
+            qdims.toString(), autoJoinTarget.getName());
       }
 
       log.info("Fact: {} minCostClause:{}", fact, minCostClause);
@@ -877,7 +878,7 @@ class JoinResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
             minCostClause.chainColumns.get(dim).toString());
         }
       }
@@ -1052,7 +1053,8 @@ class JoinResolver implements ContextRewriter {
           }
           log.warn("No join path between {} and {}", joinee.getName(), target.getName());
           if (cubeql.getDimensions().contains(joinee)) {
-            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), joinee.getName(), target.getName());
+            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
+                joinee.getName(), target.getName());
           } else {
             // if joinee is optional dim table, remove those candidate facts
             Set<CandidateTable> candidates = cubeql.getOptionalDimensionMap().get(joinee).requiredForCandidates;
@@ -1136,7 +1138,7 @@ class JoinResolver implements ContextRewriter {
     } else if (metastore.isCube(targetTableName)) {
       target = (AbstractCubeTable) metastore.getCube(targetTableName);
     } else {
-      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getValue(), targetTableName);
+      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getLensErrorInfo(), targetTableName);
     }
   }
 
@@ -1290,7 +1292,7 @@ class JoinResolver implements ContextRewriter {
       cubeql.setJoinCond(joinTree, HQLParser.getString(joinCond));
     } else {
       // No join condition specified. this should be an error
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
     }
     return joinTree;
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
index d8515d8..2fcea8b 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
@@ -93,7 +93,7 @@ class MultiFactHQLContext extends SimpleHQLContext {
     StringBuilder select = new StringBuilder();
     for (int i = 0; i < query.getSelectAST().getChildCount(); i++) {
       if (selectToFactIndex.get(i) == null) {
-        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue(),
+        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo(),
             HQLParser.getString((ASTNode) query.getSelectAST().getChild(i)));
       }
       if (selectToFactIndex.get(i).size() == 1) {

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
index b02499e..7be7ace 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
@@ -106,11 +106,12 @@ public class TimeRange {
 
   public void validate() throws LensException {
     if (partitionColumn == null || fromDate == null || toDate == null || fromDate.equals(toDate)) {
-      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
+      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo());
     }
 
     if (fromDate.after(toDate)) {
-      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getValue(), fromDate.toString(), toDate.toString());
+      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo(),
+          fromDate.toString(), toDate.toString());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
index fb1c89e..8a84249 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
@@ -67,7 +67,7 @@ class TimerangeResolver implements ContextRewriter {
     // TOK_WHERE.TOK_FUNCTION.Identifier Or, it should be right hand child of
     // AND condition TOK_WHERE.KW_AND.TOK_FUNCTION.Identifier
     if (cubeql.getWhereAST() == null || cubeql.getWhereAST().getChildCount() < 1) {
-      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getValue());
+      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getLensErrorInfo());
     }
     searchTimeRanges(cubeql.getWhereAST(), cubeql, null, 0);
   }
@@ -112,7 +112,7 @@ class TimerangeResolver implements ContextRewriter {
     String timeDimName = getColumnName((ASTNode) timenode.getChild(1));
 
     if (!cubeql.getCube().getTimedDimensions().contains(timeDimName)) {
-      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getValue(), timeDimName);
+      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getLensErrorInfo(), timeDimName);
     }
     // Replace timeDimName with column which is used for partitioning. Assume
     // the same column
@@ -155,7 +155,7 @@ class TimerangeResolver implements ContextRewriter {
       for (TimeRange range : cubeql.getTimeRanges()) {
         if (column == null) {
           if (!cubeql.getCube().getTimedDimensions().contains(col)) {
-            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getValue(), col);
+            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getLensErrorInfo(), col);
           }
           continue;
         }
@@ -213,7 +213,7 @@ class TimerangeResolver implements ContextRewriter {
                 joinPathIterator.remove();
                 if (joinPaths.isEmpty()) {
                   // This dimension doesn't have any paths left
-                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(),
+                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
                       "No valid join path available for dimension " + dimension + " which would satisfy time range "
                           + range.getFromDate() + "-" + range.getToDate());
                 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
index 9120a70..0f76c76 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
@@ -69,12 +69,12 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
 
     e = getLensExceptionInRewrite("select msr11 + msr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue());
+        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo().getErrorCode());
     // no fact has the all the dimensions queried
     e = getLensExceptionInRewrite("select dim1, test_time_dim, msr3, msr13 from basecube where "
       + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
     String regexp = String.format(CandidateTablePruneCause.CandidateTablePruneCode.COLUMN_NOT_FOUND.errorFormat,
       "Column Sets: (.*?)", "queriable together");

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
index b34c217..7e5184c 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
@@ -74,7 +74,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
   public void testQueryWithNow() throws Exception {
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube where" + " time_range_in(d_time, 'NOW - 2DAYS', 'NOW')", getConf());
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -118,19 +118,19 @@ public class TestCubeRewriter extends TestQueryRewrite {
     String qFrom4DaysBackDate = qFmt.format(from4DaysBackDate);
     LensException th = getLensExceptionInRewrite("select SUM(msr15) from testCube where"
       + " time_range_in(d_time, '"+ qFrom4DaysBackDate + "', '" + qTo + "')", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
   public void testCandidateTables() throws Exception {
     LensException th = getLensExceptionInRewrite(
       "select dim12, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     // this query should through exception because invalidMsr is invalid
     th = getLensExceptionInRewrite(
       "SELECT cityid, invalidMsr from testCube " + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -187,7 +187,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(th);
     int endIndex = MISSING_PARTITIONS.errorFormat.length() - 3;
     assertEquals(
@@ -212,7 +212,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr4) from derivedCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     // test join
     Configuration conf = getConf();
@@ -630,7 +630,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
     LensException th = getLensExceptionInRewrite(
       "select name, SUM(msr2) from testCube" + " join citydim" + " where " + TWO_DAYS_RANGE
         + " group by name", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -979,7 +979,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_MONTHS_RANGE_UPTO_HOURS, conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
 
     assertEquals(
@@ -1027,7 +1027,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     // state table is present on c1 with partition dumps and partitions added
     LensException e = getLensExceptionInRewrite("select name, capital from statedim ", conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo().getErrorCode());
     assertEquals(extractPruneCause(e), new PruneCauses.BriefAndDetailedError(
       NO_CANDIDATE_STORAGES.errorFormat,
       new HashMap<String, List<CandidateTablePruneCause>>() {
@@ -1168,13 +1168,13 @@ public class TestCubeRewriter extends TestQueryRewrite {
         + TWO_DAYS_RANGE;
 
     LensException th = getLensExceptionInRewrite(query, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo().getErrorCode());
 
     String q2 =
       "SELECT ambigdim2 from citydim join" + " statedim on citydim.stateid = statedim.id join countrydim on"
         + " statedim.countryid = countrydim.id";
     th = getLensExceptionInRewrite(q2, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -1467,7 +1467,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("TestJoinPathTimeRange: " + context.toHQL());
       fail("Expected query to fail because of invalid column life");
     } catch (LensException exc) {
-      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getValue());
+      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo().getErrorCode());
     } finally {
       // Add old column back
       cube.alterDimension(col);

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
index ca07a0d..493b8d6 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
@@ -52,7 +52,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testColumnErrors() throws Exception {
     LensException th;
     th = getLensExceptionInRewrite("select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     Assert.assertTrue(getLensExceptionErrorMessageInRewrite(
         "select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf).contains("nonexist"));
@@ -62,7 +62,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
 
     th = getLensExceptionInRewrite("select invalidexpr, " + "SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE,
         conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -337,7 +337,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testDerivedCube() throws ParseException, LensException, HiveException {
     LensException th =
       getLensExceptionInRewrite("select avgmsr from derivedCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
index 6150b14..cb63fad 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
@@ -746,10 +746,10 @@ public class TestJoinResolver extends TestQueryRewrite {
   public void testUnreachableDim() throws ParseException, LensException, HiveException {
     LensException e1 = getLensExceptionInRewrite("select urdimid from testdim2", hconf);
     assertNotNull(e1);
-    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue());
+    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo().getErrorCode());
 
     LensException e2 = getLensExceptionInRewrite("select urdimid from testcube where " + TWO_DAYS_RANGE, hconf);
     assertNotNull(e2);
-    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
index 3c3aa9c..a431717 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
@@ -68,7 +68,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getValue());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo().getErrorCode());
     }
   }
 
@@ -81,7 +81,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo().getErrorCode());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
index e5540d2..0248409 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
@@ -68,7 +68,8 @@ public abstract class TestTimeRangeWriter {
     if (failDisjoint()) {
       Assert.assertNotNull(th);
       Assert
-        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
+        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.
+            getLensErrorInfo().getErrorCode());
     } else {
       Assert.assertNull(th);
       validateDisjoint(whereClause, null);

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
index 2083ef9..7bd7b6b 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
@@ -87,7 +87,7 @@ public class TestTimeRangeWriterWithQuery extends TestQueryRewrite {
     if (!CubeTestSetup.isZerothHour()) {
       Assert.assertNotNull(th);
       Assert
-      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
+      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo().getErrorCode());
     }
     // hourly partitions for two days
     conf.setBoolean(CubeQueryConfUtil.FAIL_QUERY_ON_PARTIAL_DATA, true);

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
index c2254f1..9dc9773 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
+import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
 import lombok.NonNull;
@@ -42,21 +43,21 @@ public class ESClientException extends LensException {
     super(cause);
   }
 
-  public ESClientException(int errorCode) {
-    super(errorCode);
+  public ESClientException(LensErrorInfo errorInfo) {
+    super(errorInfo);
   }
 
-  public ESClientException(String errorMsg, int errorCode) {
-    super(errorMsg, errorCode);
+  public ESClientException(String errorMsg, LensErrorInfo errorInfo) {
+    super(errorMsg, errorInfo);
   }
 
-  public ESClientException(int errorCode, Throwable cause,
+  public ESClientException(LensErrorInfo errorInfo, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorCode, cause, errorMsgFormattingArgs);
+    super(errorInfo, cause, errorMsgFormattingArgs);
   }
 
-  public ESClientException(String errorMsg, int errorcode, Throwable cause,
+  public ESClientException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
index 8127cba..20634af 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
@@ -18,8 +18,10 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
+import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
+
 import lombok.NonNull;
 
 public class InvalidQueryException extends LensException {
@@ -40,22 +42,22 @@ public class InvalidQueryException extends LensException {
     super(cause);
   }
 
-  public InvalidQueryException(int errorCode) {
-    super(errorCode);
+  public InvalidQueryException(LensErrorInfo errorInfo) {
+    super(errorInfo);
   }
 
-  public InvalidQueryException(String errorMsg, int errorCode) {
-    super(errorMsg, errorCode);
+  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo) {
+    super(errorMsg, errorInfo);
   }
 
-  public InvalidQueryException(int errorCode, Throwable cause,
+  public InvalidQueryException(LensErrorInfo errorInfo, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorCode, cause, errorMsgFormattingArgs);
+    super(errorInfo, cause, errorMsgFormattingArgs);
   }
 
-  public InvalidQueryException(String errorMsg, int errorcode, Throwable cause,
+  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
   }
 
   public InvalidQueryException(String s, Exception e) {

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
new file mode 100644
index 0000000..449120d
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.lens.server.api;
+
+import lombok.*;
+
+@AllArgsConstructor
+public class LensErrorInfo {
+
+  @Getter
+  private int errorCode;
+  @Getter
+  private int errorWeight;
+  @Getter
+  private String errorName;
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
index c3ec099..2036dce 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
@@ -305,6 +305,6 @@ public abstract class DriverQueryPlan {
   public QueryPlan toQueryPlan() throws UnsupportedEncodingException {
     return new QueryPlan(new ArrayList<>(tablesQueried), hasSubQuery, execMode != null ? execMode.name() : null,
       scanMode != null ? scanMode.name() : null, handle,
-      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build(), false, null);
+      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build());
   }
 }


[27/50] [abbrv] lens git commit: LENS-776 : Lens Server not Starting if there is a failure in creating saved query table

Posted by ra...@apache.org.
LENS-776 : Lens Server not Starting if there is a failure in creating saved query table


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

Branch: refs/heads/current-release-line
Commit: b72c76041238bb44c6506610417104edeb974035
Parents: 5f60bdc
Author: Amruth S <am...@apache.org>
Authored: Mon Sep 21 13:54:55 2015 +0530
Committer: arshad-matin <ar...@apache.org>
Committed: Mon Sep 21 13:54:55 2015 +0530

----------------------------------------------------------------------
 lens-server/src/main/resources/lensserver-default.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/b72c7604/lens-server/src/main/resources/lensserver-default.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/main/resources/lensserver-default.xml b/lens-server/src/main/resources/lensserver-default.xml
index 6a1ac7f..3c8fc09 100644
--- a/lens-server/src/main/resources/lensserver-default.xml
+++ b/lens-server/src/main/resources/lensserver-default.xml
@@ -55,7 +55,7 @@
 
   <property>
     <name>lens.server.servicenames</name>
-    <value>session,query,metastore,scheduler,quota,savedquery</value>
+    <value>session,query,metastore,scheduler,quota</value>
     <description>These services would be started in the specified order when lens-server starts up</description>
   </property>
 
@@ -366,7 +366,7 @@
 
   <property>
     <name>lens.server.ws.resourcenames</name>
-    <value>session,metastore,query,quota,scheduler,index,log,savedquery</value>
+    <value>session,metastore,query,quota,scheduler,index,log</value>
     <description>These JAX-RS resources would be started in the specified order when lens-server starts up</description>
   </property>
 


[15/50] [abbrv] lens git commit: LENS-737 : Throw single error out with LensMultiException

Posted by ra...@apache.org.
LENS-737 : Throw single error out with LensMultiException


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

Branch: refs/heads/current-release-line
Commit: ab74f6ea442c87dd933d98d236b1f96d71086661
Parents: fb235fa
Author: Sushil Mohanty <su...@inmobi.com>
Authored: Tue Sep 8 12:00:40 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Tue Sep 8 12:00:40 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryPlan.java    |  24 --
 lens-api/src/main/resources/lens-errors.conf    | 325 +++++++++----------
 .../lens/cli/commands/LensQueryCommands.java    |  83 +++--
 .../apache/lens/cli/ExecuteQueryCommandIT.java  |   4 +-
 .../apache/lens/cli/TestLensQueryCommands.java  |   8 +-
 .../java/org/apache/lens/client/LensClient.java |   6 +-
 .../org/apache/lens/client/LensStatement.java   |  47 ++-
 .../ColUnAvailableInTimeRangeException.java     |   6 +-
 .../FieldsCannotBeQueriedTogetherException.java |   6 +-
 .../lens/cube/error/LensCubeErrorCode.java      |  76 +++--
 .../apache/lens/cube/metadata/UpdatePeriod.java |   2 +-
 .../lens/cube/parse/AggregateResolver.java      |   2 +-
 .../apache/lens/cube/parse/AliasReplacer.java   |   7 +-
 .../lens/cube/parse/BetweenTimeRangeWriter.java |   6 +-
 .../lens/cube/parse/CandidateTableResolver.java |  18 +-
 .../apache/lens/cube/parse/ColumnResolver.java  |   4 +-
 .../lens/cube/parse/CubeQueryContext.java       |  15 +-
 .../lens/cube/parse/CubeQueryRewriter.java      |   4 +-
 .../org/apache/lens/cube/parse/DateUtil.java    |   4 +-
 .../cube/parse/DenormalizationResolver.java     |   6 +-
 .../org/apache/lens/cube/parse/HQLParser.java   |   2 +-
 .../apache/lens/cube/parse/JoinResolver.java    |  12 +-
 .../lens/cube/parse/MultiFactHQLContext.java    |   2 +-
 .../org/apache/lens/cube/parse/TimeRange.java   |   5 +-
 .../lens/cube/parse/TimerangeResolver.java      |   8 +-
 .../lens/cube/parse/TestBaseCubeQueries.java    |   4 +-
 .../lens/cube/parse/TestCubeRewriter.java       |  24 +-
 .../lens/cube/parse/TestExpressionResolver.java |   6 +-
 .../lens/cube/parse/TestJoinResolver.java       |   4 +-
 .../lens/cube/parse/TestTimeRangeExtractor.java |   4 +-
 .../lens/cube/parse/TestTimeRangeWriter.java    |   3 +-
 .../parse/TestTimeRangeWriterWithQuery.java     |   2 +-
 .../driver/es/exceptions/ESClientException.java |  17 +-
 .../es/exceptions/InvalidQueryException.java    |  18 +-
 .../lens/server/api/driver/DriverQueryPlan.java |   2 +-
 .../lens/server/api/error/LensException.java    | 102 ++++--
 .../api/error/LensMultiCauseException.java      |  20 +-
 .../lens/server/error/LensServerErrorCode.java  |  18 +-
 .../UnSupportedQuerySubmitOpException.java      |   4 +-
 .../server/query/QueryExecutionServiceImpl.java |  29 +-
 .../lens/server/query/QueryServiceResource.java |  33 +-
 .../common/ErrorResponseExpectedData.java       |   2 +-
 .../lens/server/common/FailingQueryDriver.java  |   2 +-
 .../server/query/QueryAPIErrorResponseTest.java |  22 +-
 .../lens/server/query/TestQueryService.java     |  50 ++-
 45 files changed, 552 insertions(+), 496 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
index 164195b..c46972d 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryPlan.java
@@ -114,32 +114,8 @@ public class QueryPlan extends QuerySubmitResult {
   @Getter
   private QueryCostTO queryCost;
 
-  /**
-   * The error.
-   */
-  @XmlElement
-  @Getter
-  private boolean error = false;
-
-  /**
-   * The error msg.
-   */
-  @XmlElement
-  @Getter
-  private String errorMsg;
-
   public String getPlanString() throws UnsupportedEncodingException {
     return URLDecoder.decode(planString, "UTF-8");
   }
 
-  /**
-   * Instantiates a new query plan.
-   *
-   * @param hasError the has error
-   * @param errorMsg the error msg
-   */
-  public QueryPlan(boolean hasError, String errorMsg) {
-    this.error = hasError;
-    this.errorMsg = errorMsg;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-api/src/main/resources/lens-errors.conf
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/lens-errors.conf b/lens-api/src/main/resources/lens-errors.conf
index 3fb191e..5428041 100644
--- a/lens-api/src/main/resources/lens-errors.conf
+++ b/lens-api/src/main/resources/lens-errors.conf
@@ -83,179 +83,178 @@ lensCubeErrors = [
   {
     errorCode = 3002
     httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s. Please remove conflicting fields and try again."
+    payloadClass = org.apache.lens.cube.error.ConflictingFields
+  }
+
+  {
+    errorCode = 3003
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "More than one cube accessed in query : %s and %s"
+  }
+
+  {
+    errorCode = 3004
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Neither cube nor dimensions accessed in the query"
+  }
+
+  {
+    errorCode = 3005
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No timerange filter specified"
+  }
+
+  {
+    errorCode = 3006
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s is not timed dimension"
+  }
+
+  {
+    errorCode = 3007
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
+  }
+
+  {
+    errorCode = 3008
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Date value cannot be null or empty"
+  }
+
+  {
+    errorCode = 3009
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Invalid time unit %s"
+  }
+
+  {
+    errorCode = 3010
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Selecting all columns is not supported"
+  }
+
+  {
+    errorCode = 3011
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Ambiguous column %s, in dimensions %s and %s"
+  }
+
+  {
+    errorCode = 3012
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
+  }
+
+  {
+    errorCode = 3013
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "%s : Not a cube column"
+  }
+
+  {
+    errorCode = 3014
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Invalid time range"
+  }
+
+  {
+    errorCode = 3015
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "From date: %s  should be smaller than to date: %s"
+  }
+
+  {
+    errorCode = 3016
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Join target table: %s is neither dimension nor cube"
+  }
+
+  {
+    errorCode = 3017
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Configured timerange writer cannot be used. Reason %s"
+  }
+
+  {
+    errorCode = 3018
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No join condition available"
+  }
+
+  {
+    errorCode = 3019
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Expression %s is not available in any fact"
+  }
+
+  {
+    errorCode = 3020
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Default aggregate is not set for measure: %s"
+  }
+
+  {
+    errorCode = 3021
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No join path defined from %s to %s"
+  }
+
+  {
+    errorCode = 3022
+    httpStatusCode = ${BAD_REQUEST}
     errorMsg = "%s can only be queried %s. Please adjust the selected time range accordingly."
     payloadClass = org.apache.lens.cube.error.ColUnAvailableInTimeRange
   }
 
   {
-    errorCode = 3003
+    errorCode = 3023
     httpStatusCode = ${BAD_REQUEST}
-    errorMsg = "%s. Please remove conflicting fields and try again."
-    payloadClass = org.apache.lens.cube.error.ConflictingFields
+    errorMsg = "No dimension table has the queried columns for %s, columns: %s"
+  }
+
+  {
+    errorCode = 3024
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No fact table has the queried columns : %s"
+  }
+
+  {
+    errorCode = 3025
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No reference column available for : %s "
   }
 
   {
-   errorCode = 3004
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No reference column available for : %s "
-  }
-
- {
-   errorCode = 3005
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "More than one cube accessed in query : %s and %s"
- }
-
- {
-   errorCode = 3006
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Neither cube nor dimensions accessed in the query"
- }
-
- {
-   errorCode = 3007
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No timerange filter specified"
- }
-
- {
-   errorCode = 3008
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "%s is not timed dimension"
- }
-
- {
-   errorCode = 3009
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Error in parsing input date format. Expected format %s, date provided %s"
- }
-
- {
-   errorCode = 3010
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Date value cannot be null or empty"
- }
-
- {
-   errorCode = 3011
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Invalid time unit %s"
- }
-
- {
-   errorCode = 3012
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Selecting all columns is not supported"
- }
-
- {
-   errorCode = 3013
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Ambiguous column %s, in dimensions %s and %s"
- }
-
- {
-   errorCode = 3014
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Ambiguous column %s, in cube: %s and in dimension: %s"
- }
-
- {
-   errorCode = 3015
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Could not find the table containing column: %s"
- }
-
- {
-   errorCode = 3016
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "%s : Not a cube column"
- }
-
- {
-   errorCode = 3017
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate fact table available to answer the query, because %s"
- }
-
- {
-   errorCode = 3018
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No join condition available"
- }
-
- {
-   errorCode = 3019
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No storage table available for candidate fact: %s"
- }
-
- {
-   errorCode = 3020
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Default aggregate is not set for measure: %s"
- }
-
- {
-   errorCode = 3021
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Invalid time range"
- }
-
- {
-   errorCode = 3022
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "From date: %s  should be smaller than to date: %s"
- }
-
- {
-   errorCode = 3023
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No join path defined from %s to %s"
- }
-
- {
-   errorCode = 3024
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Join target table: %s is neither dimension nor cube"
- }
-
- {
-   errorCode = 3025
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No fact table has the queried columns : %s"
- }
-
- {
-   errorCode = 3026
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate dimension storage tables for dimension because %s"
- }
-
- {
-   errorCode = 3027
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No dimension table has the queried columns for %s, columns: %s"
- }
-
- {
-   errorCode = 3028
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
- }
-
- {
-   errorCode = 3029
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Configured timerange writer cannot be used. Reason %s"
- }
-
- {
-   errorCode = 3030
-   httpStatusCode = ${BAD_REQUEST}
-   errorMsg = "Expression %s is not available in any fact"
- }
+    errorCode = 3026
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Could not find the table containing column: %s"
+  }
 
+  {
+    errorCode = 3027
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate dimension table available for %s to answer the query, because %s"
+  }
+
+  {
+    errorCode = 3028
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate fact table available to answer the query, because %s"
+  }
+
+  {
+    errorCode = 3029
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No candidate dimension storage tables for dimension because %s"
+  }
+
+  {
+    errorCode = 3030
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "No storage table available for candidate fact: %s"
+  }
 ]
 
 # Overriding errors in lens-errors.conf via lens-errors-override.conf:

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 7a5b177..44c0c62 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -206,26 +206,34 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param sql      the sql
    * @param location the location
    * @return the string
+   * @throws LensAPIException
    * @throws UnsupportedEncodingException the unsupported encoding exception
    */
-  @CliCommand(value = "query explain",
-    help = "Explain execution plan of query <query-string>. Can optionally save the plan"
-      + " to a file by providing <save_location>")
-  public String explainQuery(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
-    @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") final File path)
-    throws IOException {
-    QueryPlan plan = getClient().getQueryPlan(sql);
-    if (plan.isError()) {
-      return "Explain FAILED:" + plan.getErrorMsg();
-    }
-    if (path != null && StringUtils.isNotBlank(path.getPath())) {
-      String validPath = getValidPath(path, false, false);
-      try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath), Charset.defaultCharset())) {
-        osw.write(plan.getPlanString());
+  @CliCommand(value = "query explain", help = "Explain execution plan of query <query-string>. "
+      + "Can optionally save the plan to a file by providing <save_location>")
+  public String explainQuery(@CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
+      @CliOption(key = { "save_location" }, mandatory = false, help = "<save_location>") final File path)
+    throws IOException, LensAPIException {
+    PrettyPrintable cliOutput;
+
+    try {
+      QueryPlan plan = getClient().getQueryPlan(sql).getData();
+      if (path != null && StringUtils.isNotBlank(path.getPath())) {
+        String validPath = getValidPath(path, false, false);
+        try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath),
+            Charset.defaultCharset())) {
+          osw.write(plan.getPlanString());
+        }
+        return "Saved to " + validPath;
       }
-      return "Saved to " + validPath;
+      return plan.getPlanString();
+    } catch (final LensAPIException e) {
+      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
+      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
+    } catch (final LensBriefErrorException e) {
+      cliOutput = e.getIdBriefErrorTemplate();
     }
-    return plan.getPlanString();
+    return cliOutput.toPrettyString();
   }
 
   /**
@@ -446,36 +454,47 @@ public class LensQueryCommands extends BaseLensCommand {
    * @param queryName the query name
    * @return the string
    * @throws UnsupportedEncodingException the unsupported encoding exception
+   * @throws LensAPIException
    */
   @CliCommand(value = "prepQuery prepare",
     help = "Prepapre query <query-string> and return prepare handle. Can optionaly provide <query-name>")
   public String prepare(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
     @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException {
-    return getClient().prepare(sql, queryName).toString();
+    throws UnsupportedEncodingException, LensAPIException {
+    return getClient().prepare(sql, queryName).getData().toString();
   }
 
   /**
    * Explain and prepare.
    *
-   * @param sql       the sql
-   * @param queryName the query name
+   * @param sql
+   *          the sql
+   * @param queryName
+   *          the query name
    * @return the string
-   * @throws UnsupportedEncodingException the unsupported encoding exception
+   * @throws UnsupportedEncodingException
+   *           the unsupported encoding exception
+   * @throws LensAPIException
    */
-  @CliCommand(value = "prepQuery explain",
-    help = "Explain and prepare query <query-string>. Can optionally provide <query-name>")
+  @CliCommand(value = "prepQuery explain", help = "Explain and prepare query <query-string>. "
+      + "Can optionally provide <query-name>")
   public String explainAndPrepare(
-    @CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql,
-    @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName)
-    throws UnsupportedEncodingException {
 
-    QueryPlan plan = getClient().explainAndPrepare(sql, queryName);
-    if (plan.isError()) {
-      return "Explain FAILED:" + plan.getErrorMsg();
+  @CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql,
+      @CliOption(key = { "name" }, mandatory = false, help = "<query-name>") String queryName)
+    throws UnsupportedEncodingException, LensAPIException {
+    PrettyPrintable cliOutput;
+    try {
+      QueryPlan plan = getClient().explainAndPrepare(sql, queryName).getData();
+      StringBuilder planStr = new StringBuilder(plan.getPlanString());
+      planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
+      return planStr.toString();
+    } catch (final LensAPIException e) {
+      BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage());
+      cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError);
+    } catch (final LensBriefErrorException e) {
+      cliOutput = e.getIdBriefErrorTemplate();
     }
-    StringBuilder planStr = new StringBuilder(plan.getPlanString());
-    planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
-    return planStr.toString();
+    return cliOutput.toPrettyString();
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
index b3fcccb..7f8b091 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/ExecuteQueryCommandIT.java
@@ -23,11 +23,9 @@ import static org.testng.Assert.assertTrue;
 import org.apache.lens.cli.commands.LensQueryCommands;
 import org.apache.lens.client.LensClient;
 
-import org.testng.annotations.Test;
-
 public class ExecuteQueryCommandIT extends LensCliApplicationTest {
 
-  @Test
+ // @Test
   public void testExecuteSyncQueryWithSyntaxError() {
 
     LensQueryCommands lensQueryCommands = new LensQueryCommands();

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
index 7a437a1..308c036 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java
@@ -83,11 +83,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    testExplainFailQuery(qCom);
+    //testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    testFailPreparedQuery(qCom);
+    //testFailPreparedQuery(qCom);
     // run all query commands with query metrics enabled.
     client = new LensClient();
     client.setConnectionParam("lens.query.enable.persistent.resultset.indriver", "false");
@@ -99,11 +99,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest {
     testExecuteAsyncQuery(qCom);
     testSyncResults(qCom);
     testExplainQuery(qCom);
-    testExplainFailQuery(qCom);
+    //testExplainFailQuery(qCom);
     testPreparedQuery(qCom);
     testShowPersistentResultSet(qCom);
     testPurgedFinishedResultSet(qCom);
-    testFailPreparedQuery(qCom);
+    //testFailPreparedQuery(qCom);
   }
 
 

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-client/src/main/java/org/apache/lens/client/LensClient.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
index afc76e5..5fd04c4 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java
@@ -207,7 +207,7 @@ public class LensClient {
     return getQueryDetails(QueryHandle.fromString(handle));
   }
 
-  public QueryPlan getQueryPlan(String q) {
+  public LensAPIResult<QueryPlan> getQueryPlan(String q) throws LensAPIException {
     return new LensStatement(connection).explainQuery(q);
   }
 
@@ -569,11 +569,11 @@ public class LensClient {
     return mc.updatePartitionsOfDimensionTable(table, storage, partsSpec);
   }
 
-  public QueryPrepareHandle prepare(String sql, String queryName) {
+  public LensAPIResult<QueryPrepareHandle> prepare(String sql, String queryName) throws LensAPIException {
     return statement.prepareQuery(sql, queryName);
   }
 
-  public QueryPlan explainAndPrepare(String sql, String queryName) {
+  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
     return statement.explainAndPrepare(sql, queryName);
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
----------------------------------------------------------------------
diff --git a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
index 397bd82..0a511f0 100644
--- a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
+++ b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java
@@ -127,8 +127,9 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query prepare handle
+   * @throws LensAPIException
    */
-  public QueryPrepareHandle prepareQuery(String sql, String queryName) {
+  public LensAPIResult<QueryPrepareHandle> prepareQuery(String sql, String queryName) throws LensAPIException {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -136,11 +137,14 @@ public class LensStatement {
     Client client = connection.buildClient();
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    QueryPrepareHandle handle = target.request().post(
-        Entity.entity(prepareForm(sql, "PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
-        QueryPrepareHandle.class);
-    getPreparedQuery(handle);
-    return handle;
+    Response response = target.request().post(Entity.entity(prepareForm(sql, "PREPARE", queryName),
+        MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPrepareHandle>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
   }
 
   /**
@@ -149,8 +153,9 @@ public class LensStatement {
    * @param sql       the sql
    * @param queryName the query name
    * @return the query plan
+   * @throws LensAPIException
    */
-  public QueryPlan explainAndPrepare(String sql, String queryName) {
+  public LensAPIResult<QueryPlan> explainAndPrepare(String sql, String queryName) throws LensAPIException {
     if (!connection.isOpen()) {
       throw new IllegalStateException("Lens Connection has to be " + "established before querying");
     }
@@ -159,10 +164,15 @@ public class LensStatement {
 
     WebTarget target = getPreparedQueriesWebTarget(client);
 
-    QueryPlan plan = target.request().post(
-      Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
-    return plan;
+    Response response = target.request().post(
+        Entity.entity(prepareForm(sql, "EXPLAIN_AND_PREPARE", queryName), MediaType.MULTIPART_FORM_DATA_TYPE),
+        Response.class);
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
+
   }
 
   /**
@@ -341,10 +351,11 @@ public class LensStatement {
    *
    * @param sql the sql
    * @return the query plan
+   * @throws LensAPIException
    */
-  public QueryPlan explainQuery(String sql) {
+  public LensAPIResult<QueryPlan> explainQuery(String sql) throws LensAPIException {
     if (!connection.isOpen()) {
-      throw new IllegalStateException("Lens Connection has to be " + "established before querying");
+      throw new IllegalStateException("Lens Connection has to be established before querying");
     }
 
     Client client = connection.buildClient();
@@ -356,9 +367,13 @@ public class LensStatement {
 
     WebTarget target = getQueryWebTarget(client);
 
-    QueryPlan handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
-    return handle;
+    Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    if (response.getStatus() == Response.Status.OK.getStatusCode()) {
+      return response.readEntity(new GenericType<LensAPIResult<QueryPlan>>() {});
+    }
+
+    throw new LensAPIException(response.readEntity(LensAPIResult.class));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
index dd3bb72..94badb9 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/ColUnAvailableInTimeRangeException.java
@@ -35,7 +35,7 @@ public class ColUnAvailableInTimeRangeException extends LensException {
 
   public ColUnAvailableInTimeRangeException(@NonNull final ColUnAvailableInTimeRange colUnAvailableInTimeRange) {
 
-    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue());
+    super(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo());
     this.colUnAvailableInTimeRange = colUnAvailableInTimeRange;
   }
 
@@ -52,8 +52,8 @@ public class ColUnAvailableInTimeRangeException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(), errorMsg, stackTrace,
-        colUnAvailableInTimeRange);
+    return LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
+        errorMsg, stackTrace, colUnAvailableInTimeRange);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
index 65b96d7..bcd42dc 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/FieldsCannotBeQueriedTogetherException.java
@@ -37,7 +37,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
 
   public FieldsCannotBeQueriedTogetherException(@NonNull final ConflictingFields conflictingFields) {
 
-    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue());
+    super(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo());
     this.conflictingFields = conflictingFields;
   }
 
@@ -52,7 +52,7 @@ public class FieldsCannotBeQueriedTogetherException extends LensException {
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
       final String stackTrace) {
 
-    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getValue(), errorMsg, stackTrace,
-        conflictingFields);
+    return LensErrorTO.composedOf(FIELDS_CANNOT_BE_QUERIED_TOGETHER.getLensErrorInfo().getErrorCode(),
+        errorMsg, stackTrace, conflictingFields);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
index 1fe74e2..73a584f 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/error/LensCubeErrorCode.java
@@ -18,46 +18,50 @@
  */
 package org.apache.lens.cube.error;
 
-public enum LensCubeErrorCode {
+import org.apache.lens.server.api.LensErrorInfo;
 
-  SYNTAX_ERROR(3001),
-  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3002),
-  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3003),
-  NO_REF_COL_AVAILABLE(3004),
-  MORE_THAN_ONE_CUBE(3005),
-  NEITHER_CUBE_NOR_DIMENSION(3006),
-  NO_TIMERANGE_FILTER(3007),
-  NOT_A_TIMED_DIMENSION(3008),
-  WRONG_TIME_RANGE_FORMAT(3009),
-  NULL_DATE_VALUE(3010),
-  INVALID_TIME_UNIT(3011),
-  ALL_COLUMNS_NOT_SUPPORTED(3012),
-  AMBIGOUS_DIM_COLUMN(3013),
-  AMBIGOUS_CUBE_COLUMN(3014),
-  COLUMN_NOT_FOUND(3015),
-  NOT_A_CUBE_COLUMN(3016),
-  NO_CANDIDATE_FACT_AVAILABLE(3017),
-  NO_JOIN_CONDITION_AVAIABLE(3018),
-  NO_STORAGE_TABLE_AVAIABLE(3019),
-  NO_DEFAULT_AGGREGATE(3020),
-  INVALID_TIME_RANGE(3021),
-  FROM_AFTER_TO(3022),
-  NO_JOIN_PATH(3023),
-  JOIN_TARGET_NOT_CUBE_TABLE(3024),
-  NO_FACT_HAS_COLUMN(3025),
-  NO_CANDIDATE_DIM_STORAGE_TABLES(3026),
-  NO_DIM_HAS_COLUMN(3027),
-  NO_CANDIDATE_DIM_AVAILABLE(3028),
-  CANNOT_USE_TIMERANGE_WRITER(3029),
-  EXPRESSION_NOT_IN_ANY_FACT(3030);
+public enum LensCubeErrorCode {
+  // Error codes same for drivers
+  SYNTAX_ERROR(3001, 0),
+  FIELDS_CANNOT_BE_QUERIED_TOGETHER(3002, 0),
+  MORE_THAN_ONE_CUBE(3003, 0),
+  NEITHER_CUBE_NOR_DIMENSION(3004, 0),
+  NO_TIMERANGE_FILTER(3005, 0),
+  NOT_A_TIMED_DIMENSION(3006, 0),
+  WRONG_TIME_RANGE_FORMAT(3007, 0),
+  NULL_DATE_VALUE(3008, 0),
+  INVALID_TIME_UNIT(3009, 0),
+  ALL_COLUMNS_NOT_SUPPORTED(3010, 0),
+  AMBIGOUS_DIM_COLUMN(3011, 0),
+  AMBIGOUS_CUBE_COLUMN(3012, 0),
+  NOT_A_CUBE_COLUMN(3013, 0),
+  INVALID_TIME_RANGE(3014, 0),
+  FROM_AFTER_TO(3015, 0),
+  JOIN_TARGET_NOT_CUBE_TABLE(3016, 0),
+  // Error codes different for drivers
+  CANNOT_USE_TIMERANGE_WRITER(3017, 100),
+  NO_DEFAULT_AGGREGATE(3018, 200),
+  EXPRESSION_NOT_IN_ANY_FACT(3019, 300),
+  NO_JOIN_CONDITION_AVAIABLE(3020, 400),
+  NO_JOIN_PATH(3021, 500),
+  COLUMN_UNAVAILABLE_IN_TIME_RANGE(3022, 600),
+  NO_DIM_HAS_COLUMN(3023, 700),
+  NO_FACT_HAS_COLUMN(3024, 800),
+  NO_REF_COL_AVAILABLE(3025, 900),
+  COLUMN_NOT_FOUND(3026, 1000),
+  NO_CANDIDATE_DIM_AVAILABLE(3027, 1100),
+  NO_CANDIDATE_FACT_AVAILABLE(3028, 1200),
+  NO_CANDIDATE_DIM_STORAGE_TABLES(3029, 1300),
+  NO_STORAGE_TABLE_AVAIABLE(3030, 1400);
 
-  public int getValue() {
-    return this.errorCode;
+  public LensErrorInfo getLensErrorInfo() {
+    return this.errorInfo;
   }
 
-  LensCubeErrorCode(final int code) {
-    this.errorCode = code;
+  LensCubeErrorCode(final int code, final int weight) {
+    this.errorInfo = new LensErrorInfo(code, weight, name());
   }
 
-  private final int errorCode;
+  private final LensErrorInfo errorInfo;
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
index 6c61e94..f192463 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
@@ -191,7 +191,7 @@ public enum UpdatePeriod implements Named {
         return up;
       }
     }
-    throw new LensException(LensCubeErrorCode.INVALID_TIME_UNIT.getValue(), unitName);
+    throw new LensException(LensCubeErrorCode.INVALID_TIME_UNIT.getLensErrorInfo(), unitName);
   }
 
   public DateFormat format() {

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
index 9c0f936..b544a67 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AggregateResolver.java
@@ -188,7 +188,7 @@ class AggregateResolver implements ContextRewriter {
         String aggregateFn = measure.getAggregate();
 
         if (StringUtils.isBlank(aggregateFn)) {
-          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getValue(), colname);
+          throw new LensException(LensCubeErrorCode.NO_DEFAULT_AGGREGATE.getLensErrorInfo(), colname);
         }
         ASTNode fnroot = new ASTNode(new CommonToken(HiveParser.TOK_FUNCTION));
         fnroot.setParent(node.getParent());

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
index 98e38d5..0656049 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/AliasReplacer.java
@@ -145,20 +145,21 @@ class AliasReplacer implements ContextRewriter {
           if (!inCube) {
             String prevDim = colToTableAlias.get(col.toLowerCase());
             if (prevDim != null && !prevDim.equals(dim.getName())) {
-              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue(), col, prevDim, dim.getName());
+              throw new LensException(LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo(),
+                  col, prevDim, dim.getName());
             }
             String dimAlias = cubeql.getAliasForTableName(dim.getName());
             colToTableAlias.put(col.toLowerCase(), dimAlias);
             tqc.addColumnsQueried(dimAlias, col.toLowerCase());
           } else {
             // throw error because column is in both cube and dimension table
-            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue(), col,
+            throw new LensException(LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo(), col,
                 cubeql.getCube().getName(), dim.getName());
           }
         }
       }
       if (colToTableAlias.get(col.toLowerCase()) == null) {
-        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getValue(), col);
+        throw new LensException(LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo(), col);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
index 4bd7cc8..bd19d4c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/BetweenTimeRangeWriter.java
@@ -52,7 +52,7 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
       while (it.hasNext()) {
         FactPartition part = it.next();
         if (part.hasContainingPart()) {
-          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+          throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Partition has containing part");
         }
         if (first == null) {
@@ -60,11 +60,11 @@ public class BetweenTimeRangeWriter implements TimeRangeWriter {
         } else {
           // validate partcol, update period are same for both
           if (!first.getPartCol().equalsIgnoreCase(part.getPartCol())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Part columns are different in partitions");
           }
           if (!first.getPeriod().equals(part.getPeriod())) {
-            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue(),
+            throw new LensException(LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo(),
               "Partitions are in different update periods");
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
index 69fbcc5..f81f3d5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTableResolver.java
@@ -92,8 +92,8 @@ class CandidateTableResolver implements ContextRewriter {
       if (cubeql.getCube() != null) {
         List<CubeFactTable> factTables = cubeql.getMetastoreClient().getAllFacts(cubeql.getCube());
         if (factTables.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), cubeql.getCube().getName()
-            + " does not have any facts");
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(),
+              cubeql.getCube().getName() + " does not have any facts");
         }
         for (CubeFactTable fact : factTables) {
           CandidateFact cfact = new CandidateFact(fact, cubeql.getCube());
@@ -122,7 +122,7 @@ class CandidateTableResolver implements ContextRewriter {
       List<CubeDimensionTable> dimtables = cubeql.getMetastoreClient().getAllDimensionTables(dim);
       if (dimtables.isEmpty()) {
         if (!optional) {
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(), dim.getName(),
             "Dimension tables do not exist");
         } else {
           log.info("Not considering optional dimension {}  as, No dimension tables exist", dim);
@@ -284,7 +284,7 @@ class CandidateTableResolver implements ContextRewriter {
       Set<String> dimExprs = new HashSet<String>(cubeql.getQueriedExprs());
       dimExprs.removeAll(cubeql.getQueriedExprsWithMeasures());
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
           (!queriedDimAttrs.isEmpty() ? queriedDimAttrs.toString() : "")
           +  (!dimExprs.isEmpty() ? dimExprs.toString() : ""));
       }
@@ -308,14 +308,14 @@ class CandidateTableResolver implements ContextRewriter {
         String msrString = (!queriedMsrs.isEmpty() ? queriedMsrs.toString() : "")
           + (!cubeql.getQueriedExprsWithMeasures().isEmpty() ? cubeql.getQueriedExprsWithMeasures().toString() : "");
         if (cfactset.isEmpty()) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
         }
         cubeql.getCandidateFactSets().addAll(cfactset);
         cubeql.pruneCandidateFactWithCandidateSet(CandidateTablePruneCause.columnNotFound(queriedMsrs,
           cubeql.getQueriedExprsWithMeasures()));
 
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(), msrString);
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(), msrString);
         }
       }
     }
@@ -431,7 +431,7 @@ class CandidateTableResolver implements ContextRewriter {
           OptionalDimCtx optdim = cubeql.getOptionalDimensionMap().get(dim);
           if ((cubeql.getDimensions() != null && cubeql.getDimensions().contains(dim))
             || (optdim != null && optdim.isRequiredInJoinChain)) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
                 cubeql.getAutoJoinCtx().getAllJoinPathColumnsOfTable(dim).toString());
           } else {
             // remove it from optional tables
@@ -474,7 +474,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
       }
       if (cubeql.getCandidateFacts().size() == 0) {
-        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+        throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
             colSet == null ? "NULL" : colSet.toString());
       }
     }
@@ -669,7 +669,7 @@ class CandidateTableResolver implements ContextRewriter {
         }
 
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(), cubeql
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(), cubeql
             .getColumnsQueried(dim.getName()).toString());
         }
       }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
index dfe0c32..b95595a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ColumnResolver.java
@@ -55,7 +55,7 @@ class ColumnResolver implements ContextRewriter {
       if (star != null) {
         int starType = star.getToken().getType();
         if (TOK_FUNCTIONSTAR == starType || TOK_ALLCOLREF == starType) {
-          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getValue());
+          throw new LensException(LensCubeErrorCode.ALL_COLUMNS_NOT_SUPPORTED.getLensErrorInfo());
         }
       }
     }
@@ -70,7 +70,7 @@ class ColumnResolver implements ContextRewriter {
     for (String table : cubeql.getTblAliasToColumns().keySet()) {
       if (!CubeQueryContext.DEFAULT_TABLE.equalsIgnoreCase(table)) {
         if (!cubeql.addQueriedTable(table)) {
-          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+          throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
index 16429f0..450d172 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryContext.java
@@ -224,7 +224,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addJoinChain(alias, false);
       if (!added) {
         log.info("Queried tables do not exist. Missing table:{}", alias);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
       }
     }
   }
@@ -259,7 +259,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       boolean added = addQueriedTable(alias, destTable, isOptional, true);
       if (!added) {
         log.info("Queried tables do not exist. Missing tables:{}", destTable);
-        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue());
+        throw new LensException(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo());
       }
       log.info("Added join chain for {}", destTable);
       return true;
@@ -308,7 +308,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
       if (metastoreClient.isCube(tblName)) {
         if (cube != null) {
           if (!cube.getName().equalsIgnoreCase(tblName)) {
-            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getValue(), cube.getName(), tblName);
+            throw new LensException(LensCubeErrorCode.MORE_THAN_ONE_CUBE.getLensErrorInfo(), cube.getName(), tblName);
           }
         }
         cube = metastoreClient.getCube(tblName);
@@ -687,7 +687,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         fromString = fact.getStorageString(getAliasForTableName(cube.getName()));
       } else {
         if (dimensions.size() != 1) {
-          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+          throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
         }
         Dimension dim = dimensions.iterator().next();
         fromString = dimsToQuery.get(dim).getStorageString(getAliasForTableName(dim.getName()));
@@ -740,7 +740,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
         dimsToQuery.get(cubeTbls.get(joiningTable)).setWhereClauseAdded();
       }
     } else {
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
     }
   }
 
@@ -804,7 +804,8 @@ public class CubeQueryContext implements TrackQueriedColumns {
               }
             }
           }
-          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue(), dim.getName(), reason);
+          throw new LensException(LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo(),
+              dim.getName(), reason);
         }
       }
     }
@@ -839,7 +840,7 @@ public class CubeQueryContext implements TrackQueriedColumns {
             }
           }
         }
-        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue(), reason);
+        throw new LensException(LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo(), reason);
       }
     }
     return facts;

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
index 0dfd7da..e0759b0 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CubeQueryRewriter.java
@@ -193,7 +193,7 @@ public class CubeQueryRewriter {
       analyzer = new CubeSemanticAnalyzer(conf, hconf);
       analyzer.analyze(astnode, qlCtx);
     } catch (SemanticException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     }
     CubeQueryContext ctx = new CubeQueryContext(astnode, analyzer.getCubeQB(), conf, hconf);
     rewrite(rewriters, ctx);
@@ -210,7 +210,7 @@ public class CubeQueryRewriter {
       tree = pd.parse(command, qlCtx, false);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     }
     return rewrite(tree);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
index 90ea63c..cbcc76c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
@@ -156,13 +156,13 @@ public final class DateUtil {
       return ABSDATE_PARSER.get().parse(getAbsDateFormatString(str));
     } catch (ParseException e) {
       log.error("Invalid date format. expected only {} date provided:{}", ABSDATE_FMT, str, e);
-      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getValue(), ABSDATE_FMT, str);
+      throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getLensErrorInfo(), ABSDATE_FMT, str);
     }
   }
 
   public static Date resolveRelativeDate(String str, Date now) throws LensException {
     if (StringUtils.isBlank(str)) {
-      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getValue());
+      throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getLensErrorInfo());
     }
 
     // Resolve NOW with proper granularity

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
index 3ef9652..a576f3a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DenormalizationResolver.java
@@ -251,7 +251,7 @@ public class DenormalizationResolver implements ContextRewriter {
               }
             }
             if (refered.references.isEmpty()) {
-              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getValue(), refered);
+              throw new LensException(LensCubeErrorCode.NO_REF_COL_AVAILABLE.getLensErrorInfo(), refered);
             }
             PickedReference picked = new PickedReference(refered.references.iterator().next(),
               cubeql.getAliasForTableName(refered.srcTable.getName()), tbl);
@@ -400,7 +400,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateFacts().size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getValue(),
+          throw new LensException(LensCubeErrorCode.NO_FACT_HAS_COLUMN.getLensErrorInfo(),
               cubeql.getColumnsQueried(cubeql.getCube().getName()).toString());
         }
         cubeql.pruneCandidateFactSet(CandidateTablePruneCode.COLUMN_NOT_FOUND);
@@ -422,7 +422,7 @@ public class DenormalizationResolver implements ContextRewriter {
           }
 
           if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(),
+            throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(),
               dim.toString(), cubeql.getColumnsQueried(dim.getName()).toString());
           }
         }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
index 586629f..1964e32 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/HQLParser.java
@@ -148,7 +148,7 @@ public final class HQLParser {
       tree = driver.parse(query, ctx);
       tree = ParseUtils.findRootNonNullToken(tree);
     } catch (ParseException e) {
-      throw new LensException(SYNTAX_ERROR.getValue(), e, e.getMessage());
+      throw new LensException(SYNTAX_ERROR.getLensErrorInfo(), e, e.getMessage());
     } catch (IOException e) {
       throw new RuntimeException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
index 826a59d..c7f1e2a 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/JoinResolver.java
@@ -847,7 +847,8 @@ class JoinResolver implements ContextRewriter {
       }
 
       if (minCostClause == null) {
-        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), qdims.toString(), autoJoinTarget.getName());
+        throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
+            qdims.toString(), autoJoinTarget.getName());
       }
 
       log.info("Fact: {} minCostClause:{}", fact, minCostClause);
@@ -877,7 +878,7 @@ class JoinResolver implements ContextRewriter {
           }
         }
         if (cubeql.getCandidateDimTables().get(dim).size() == 0) {
-          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue(), dim.getName(),
+          throw new LensException(LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo(), dim.getName(),
             minCostClause.chainColumns.get(dim).toString());
         }
       }
@@ -1052,7 +1053,8 @@ class JoinResolver implements ContextRewriter {
           }
           log.warn("No join path between {} and {}", joinee.getName(), target.getName());
           if (cubeql.getDimensions().contains(joinee)) {
-            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(), joinee.getName(), target.getName());
+            throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
+                joinee.getName(), target.getName());
           } else {
             // if joinee is optional dim table, remove those candidate facts
             Set<CandidateTable> candidates = cubeql.getOptionalDimensionMap().get(joinee).requiredForCandidates;
@@ -1136,7 +1138,7 @@ class JoinResolver implements ContextRewriter {
     } else if (metastore.isCube(targetTableName)) {
       target = (AbstractCubeTable) metastore.getCube(targetTableName);
     } else {
-      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getValue(), targetTableName);
+      throw new LensException(LensCubeErrorCode.JOIN_TARGET_NOT_CUBE_TABLE.getLensErrorInfo(), targetTableName);
     }
   }
 
@@ -1290,7 +1292,7 @@ class JoinResolver implements ContextRewriter {
       cubeql.setJoinCond(joinTree, HQLParser.getString(joinCond));
     } else {
       // No join condition specified. this should be an error
-      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+      throw new LensException(LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo());
     }
     return joinTree;
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
index d8515d8..2fcea8b 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/MultiFactHQLContext.java
@@ -93,7 +93,7 @@ class MultiFactHQLContext extends SimpleHQLContext {
     StringBuilder select = new StringBuilder();
     for (int i = 0; i < query.getSelectAST().getChildCount(); i++) {
       if (selectToFactIndex.get(i) == null) {
-        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue(),
+        throw new LensException(LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo(),
             HQLParser.getString((ASTNode) query.getSelectAST().getChild(i)));
       }
       if (selectToFactIndex.get(i).size() == 1) {

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
index b02499e..7be7ace 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
@@ -106,11 +106,12 @@ public class TimeRange {
 
   public void validate() throws LensException {
     if (partitionColumn == null || fromDate == null || toDate == null || fromDate.equals(toDate)) {
-      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
+      throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo());
     }
 
     if (fromDate.after(toDate)) {
-      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getValue(), fromDate.toString(), toDate.toString());
+      throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo(),
+          fromDate.toString(), toDate.toString());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
index fb1c89e..8a84249 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
@@ -67,7 +67,7 @@ class TimerangeResolver implements ContextRewriter {
     // TOK_WHERE.TOK_FUNCTION.Identifier Or, it should be right hand child of
     // AND condition TOK_WHERE.KW_AND.TOK_FUNCTION.Identifier
     if (cubeql.getWhereAST() == null || cubeql.getWhereAST().getChildCount() < 1) {
-      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getValue());
+      throw new LensException(LensCubeErrorCode.NO_TIMERANGE_FILTER.getLensErrorInfo());
     }
     searchTimeRanges(cubeql.getWhereAST(), cubeql, null, 0);
   }
@@ -112,7 +112,7 @@ class TimerangeResolver implements ContextRewriter {
     String timeDimName = getColumnName((ASTNode) timenode.getChild(1));
 
     if (!cubeql.getCube().getTimedDimensions().contains(timeDimName)) {
-      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getValue(), timeDimName);
+      throw new LensException(LensCubeErrorCode.NOT_A_TIMED_DIMENSION.getLensErrorInfo(), timeDimName);
     }
     // Replace timeDimName with column which is used for partitioning. Assume
     // the same column
@@ -155,7 +155,7 @@ class TimerangeResolver implements ContextRewriter {
       for (TimeRange range : cubeql.getTimeRanges()) {
         if (column == null) {
           if (!cubeql.getCube().getTimedDimensions().contains(col)) {
-            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getValue(), col);
+            throw new LensException(LensCubeErrorCode.NOT_A_CUBE_COLUMN.getLensErrorInfo(), col);
           }
           continue;
         }
@@ -213,7 +213,7 @@ class TimerangeResolver implements ContextRewriter {
                 joinPathIterator.remove();
                 if (joinPaths.isEmpty()) {
                   // This dimension doesn't have any paths left
-                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getValue(),
+                  throw new LensException(LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo(),
                       "No valid join path available for dimension " + dimension + " which would satisfy time range "
                           + range.getFromDate() + "-" + range.getToDate());
                 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
index 9120a70..0f76c76 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestBaseCubeQueries.java
@@ -69,12 +69,12 @@ public class TestBaseCubeQueries extends TestQueryRewrite {
 
     e = getLensExceptionInRewrite("select msr11 + msr2 from basecube" + " where " + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getValue());
+        LensCubeErrorCode.EXPRESSION_NOT_IN_ANY_FACT.getLensErrorInfo().getErrorCode());
     // no fact has the all the dimensions queried
     e = getLensExceptionInRewrite("select dim1, test_time_dim, msr3, msr13 from basecube where "
       + TWO_DAYS_RANGE, conf);
     assertEquals(e.getErrorCode(),
-        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+        LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
     String regexp = String.format(CandidateTablePruneCause.CandidateTablePruneCode.COLUMN_NOT_FOUND.errorFormat,
       "Column Sets: (.*?)", "queriable together");

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
index b34c217..7e5184c 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestCubeRewriter.java
@@ -74,7 +74,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
   public void testQueryWithNow() throws Exception {
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube where" + " time_range_in(d_time, 'NOW - 2DAYS', 'NOW')", getConf());
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -118,19 +118,19 @@ public class TestCubeRewriter extends TestQueryRewrite {
     String qFrom4DaysBackDate = qFmt.format(from4DaysBackDate);
     LensException th = getLensExceptionInRewrite("select SUM(msr15) from testCube where"
       + " time_range_in(d_time, '"+ qFrom4DaysBackDate + "', '" + qTo + "')", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
   public void testCandidateTables() throws Exception {
     LensException th = getLensExceptionInRewrite(
       "select dim12, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     // this query should through exception because invalidMsr is invalid
     th = getLensExceptionInRewrite(
       "SELECT cityid, invalidMsr from testCube " + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -187,7 +187,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(th);
     int endIndex = MISSING_PARTITIONS.errorFormat.length() - 3;
     assertEquals(
@@ -212,7 +212,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException th = getLensExceptionInRewrite(
       "select SUM(msr4) from derivedCube" + " where " + TWO_DAYS_RANGE, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     // test join
     Configuration conf = getConf();
@@ -630,7 +630,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
     LensException th = getLensExceptionInRewrite(
       "select name, SUM(msr2) from testCube" + " join citydim" + " where " + TWO_DAYS_RANGE
         + " group by name", getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.NO_JOIN_CONDITION_AVAIABLE.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -979,7 +979,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     LensException e = getLensExceptionInRewrite(
       "select SUM(msr2) from testCube" + " where " + TWO_MONTHS_RANGE_UPTO_HOURS, conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
     PruneCauses.BriefAndDetailedError pruneCauses = extractPruneCause(e);
 
     assertEquals(
@@ -1027,7 +1027,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
 
     // state table is present on c1 with partition dumps and partitions added
     LensException e = getLensExceptionInRewrite("select name, capital from statedim ", conf);
-    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getValue());
+    assertEquals(e.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_DIM_AVAILABLE.getLensErrorInfo().getErrorCode());
     assertEquals(extractPruneCause(e), new PruneCauses.BriefAndDetailedError(
       NO_CANDIDATE_STORAGES.errorFormat,
       new HashMap<String, List<CandidateTablePruneCause>>() {
@@ -1168,13 +1168,13 @@ public class TestCubeRewriter extends TestQueryRewrite {
         + TWO_DAYS_RANGE;
 
     LensException th = getLensExceptionInRewrite(query, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_CUBE_COLUMN.getLensErrorInfo().getErrorCode());
 
     String q2 =
       "SELECT ambigdim2 from citydim join" + " statedim on citydim.stateid = statedim.id join countrydim on"
         + " statedim.countryid = countrydim.id";
     th = getLensExceptionInRewrite(q2, getConf());
-    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getValue());
+    assertEquals(th.getErrorCode(), LensCubeErrorCode.AMBIGOUS_DIM_COLUMN.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -1467,7 +1467,7 @@ public class TestCubeRewriter extends TestQueryRewrite {
       System.out.println("TestJoinPathTimeRange: " + context.toHQL());
       fail("Expected query to fail because of invalid column life");
     } catch (LensException exc) {
-      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getValue());
+      assertEquals(exc.getErrorCode(), LensCubeErrorCode.NO_JOIN_PATH.getLensErrorInfo().getErrorCode());
     } finally {
       // Add old column back
       cube.alterDimension(col);

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
index ca07a0d..493b8d6 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestExpressionResolver.java
@@ -52,7 +52,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testColumnErrors() throws Exception {
     LensException th;
     th = getLensExceptionInRewrite("select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
 
     Assert.assertTrue(getLensExceptionErrorMessageInRewrite(
         "select nocolexpr, SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE, conf).contains("nonexist"));
@@ -62,7 +62,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
 
     th = getLensExceptionInRewrite("select invalidexpr, " + "SUM(msr2) from testCube" + " where " + TWO_DAYS_RANGE,
         conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test
@@ -337,7 +337,7 @@ public class TestExpressionResolver extends TestQueryRewrite {
   public void testDerivedCube() throws ParseException, LensException, HiveException {
     LensException th =
       getLensExceptionInRewrite("select avgmsr from derivedCube" + " where " + TWO_DAYS_RANGE, conf);
-    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getValue());
+    Assert.assertEquals(th.getErrorCode(), LensCubeErrorCode.COLUMN_NOT_FOUND.getLensErrorInfo().getErrorCode());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
index 6150b14..cb63fad 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestJoinResolver.java
@@ -746,10 +746,10 @@ public class TestJoinResolver extends TestQueryRewrite {
   public void testUnreachableDim() throws ParseException, LensException, HiveException {
     LensException e1 = getLensExceptionInRewrite("select urdimid from testdim2", hconf);
     assertNotNull(e1);
-    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getValue());
+    assertEquals(e1.getErrorCode(), LensCubeErrorCode.NO_DIM_HAS_COLUMN.getLensErrorInfo().getErrorCode());
 
     LensException e2 = getLensExceptionInRewrite("select urdimid from testcube where " + TWO_DAYS_RANGE, hconf);
     assertNotNull(e2);
-    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getValue());
+    assertEquals(e2.getErrorCode(), LensCubeErrorCode.NO_CANDIDATE_FACT_AVAILABLE.getLensErrorInfo().getErrorCode());
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
index 3c3aa9c..a431717 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeExtractor.java
@@ -68,7 +68,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getValue());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo().getErrorCode());
     }
   }
 
@@ -81,7 +81,7 @@ public class TestTimeRangeExtractor extends TestQueryRewrite {
       Assert.fail("Should not reach here");
     } catch (LensException exc) {
       Assert.assertNotNull(exc);
-      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getValue());
+      Assert.assertEquals(exc.getErrorCode(), LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo().getErrorCode());
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
index e5540d2..0248409 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriter.java
@@ -68,7 +68,8 @@ public abstract class TestTimeRangeWriter {
     if (failDisjoint()) {
       Assert.assertNotNull(th);
       Assert
-        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
+        .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.
+            getLensErrorInfo().getErrorCode());
     } else {
       Assert.assertNull(th);
       validateDisjoint(whereClause, null);

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
index 2083ef9..7bd7b6b 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestTimeRangeWriterWithQuery.java
@@ -87,7 +87,7 @@ public class TestTimeRangeWriterWithQuery extends TestQueryRewrite {
     if (!CubeTestSetup.isZerothHour()) {
       Assert.assertNotNull(th);
       Assert
-      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getValue());
+      .assertEquals(th.getErrorCode(), LensCubeErrorCode.CANNOT_USE_TIMERANGE_WRITER.getLensErrorInfo().getErrorCode());
     }
     // hourly partitions for two days
     conf.setBoolean(CubeQueryConfUtil.FAIL_QUERY_ON_PARTIAL_DATA, true);

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
index c2254f1..9dc9773 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/ESClientException.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
+import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
 import lombok.NonNull;
@@ -42,21 +43,21 @@ public class ESClientException extends LensException {
     super(cause);
   }
 
-  public ESClientException(int errorCode) {
-    super(errorCode);
+  public ESClientException(LensErrorInfo errorInfo) {
+    super(errorInfo);
   }
 
-  public ESClientException(String errorMsg, int errorCode) {
-    super(errorMsg, errorCode);
+  public ESClientException(String errorMsg, LensErrorInfo errorInfo) {
+    super(errorMsg, errorInfo);
   }
 
-  public ESClientException(int errorCode, Throwable cause,
+  public ESClientException(LensErrorInfo errorInfo, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorCode, cause, errorMsgFormattingArgs);
+    super(errorInfo, cause, errorMsgFormattingArgs);
   }
 
-  public ESClientException(String errorMsg, int errorcode, Throwable cause,
+  public ESClientException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
                            @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
----------------------------------------------------------------------
diff --git a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
index 8127cba..20634af 100644
--- a/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
+++ b/lens-driver-es/src/main/java/org/apache/lens/driver/es/exceptions/InvalidQueryException.java
@@ -18,8 +18,10 @@
  */
 package org.apache.lens.driver.es.exceptions;
 
+import org.apache.lens.server.api.LensErrorInfo;
 import org.apache.lens.server.api.error.LensException;
 
+
 import lombok.NonNull;
 
 public class InvalidQueryException extends LensException {
@@ -40,22 +42,22 @@ public class InvalidQueryException extends LensException {
     super(cause);
   }
 
-  public InvalidQueryException(int errorCode) {
-    super(errorCode);
+  public InvalidQueryException(LensErrorInfo errorInfo) {
+    super(errorInfo);
   }
 
-  public InvalidQueryException(String errorMsg, int errorCode) {
-    super(errorMsg, errorCode);
+  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo) {
+    super(errorMsg, errorInfo);
   }
 
-  public InvalidQueryException(int errorCode, Throwable cause,
+  public InvalidQueryException(LensErrorInfo errorInfo, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorCode, cause, errorMsgFormattingArgs);
+    super(errorInfo, cause, errorMsgFormattingArgs);
   }
 
-  public InvalidQueryException(String errorMsg, int errorcode, Throwable cause,
+  public InvalidQueryException(String errorMsg, LensErrorInfo errorInfo, Throwable cause,
                                @NonNull Object... errorMsgFormattingArgs) {
-    super(errorMsg, errorcode, cause, errorMsgFormattingArgs);
+    super(errorMsg, errorInfo, cause, errorMsgFormattingArgs);
   }
 
   public InvalidQueryException(String s, Exception e) {

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
index c3ec099..2036dce 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryPlan.java
@@ -305,6 +305,6 @@ public abstract class DriverQueryPlan {
   public QueryPlan toQueryPlan() throws UnsupportedEncodingException {
     return new QueryPlan(new ArrayList<>(tablesQueried), hasSubQuery, execMode != null ? execMode.name() : null,
       scanMode != null ? scanMode.name() : null, handle,
-      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build(), false, null);
+      URLEncoder.encode(getPlan(), "UTF-8"), new QueryCostTOBuilder(getCost()).build());
   }
 }


[04/50] [abbrv] lens git commit: LENS-753: Queue number for queries in submitted queue

Posted by ra...@apache.org.
LENS-753: Queue number for queries in submitted queue


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/2f22f60b
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/2f22f60b
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/2f22f60b

Branch: refs/heads/current-release-line
Commit: 2f22f60b2d50c20ec9291483d73d4fd735eb8ef9
Parents: fa8e520
Author: Akshay Goyal <ak...@gmail.com>
Authored: Thu Aug 27 20:52:52 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Thu Aug 27 20:52:52 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryStatus.java  | 11 +++++++
 .../lens/cli/commands/LensQueryCommands.java    |  3 ++
 .../server/api/driver/DriverQueryStatus.java    | 14 +++++++--
 .../server/api/query/FinishedLensQuery.java     |  2 +-
 .../lens/server/api/query/QueryContext.java     |  2 +-
 .../query/collect/ImmutableQueryCollection.java |  6 ++++
 .../server/query/QueryExecutionServiceImpl.java | 15 +++++-----
 .../DefaultEstimatedQueryCollection.java        |  5 ++++
 .../query/collect/DefaultQueryCollection.java   | 20 +++++++++++++
 .../query/collect/MutableQueryCollection.java   |  1 +
 .../ThreadSafeEstimatedQueryCollection.java     |  5 ++++
 .../collect/ThreadSafeQueryCollection.java      |  5 ++++
 .../collect/DefaultQueryCollectionTest.java     | 23 +++++++++++++++
 .../server/query/collect/QueryCollectUtil.java  | 30 ++++++++++++++++++++
 14 files changed, 130 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
index 9614caa..0d73c3f 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
@@ -39,6 +39,8 @@ import lombok.*;
  *
  * @param progress
  *          the progress
+ * @param queueNumber
+ *          the queue number
  * @param status
  *          the status
  * @param statusMessage
@@ -121,6 +123,14 @@ public class QueryStatus implements Serializable {
   private double progress;
 
   /**
+   * The running queue number. A non zero value gives the queue number. Queue number zero mean either the query is in
+   * waiting or completed state.
+   */
+  @XmlElement
+  @Getter
+  private int queueNumber;
+
+  /**
    * The status.
    */
   @XmlElement
@@ -168,6 +178,7 @@ public class QueryStatus implements Serializable {
     StringBuilder str = new StringBuilder(status.toString()).append(':').append(statusMessage);
     if (status.equals(Status.RUNNING)) {
       str.append(" - Progress:").append(progress).append(":").append(progressMessage);
+      str.append(" - Queue number:").append(queueNumber);
     }
     if (status.equals(Status.SUCCESSFUL)) {
       if (isResultSetAvailable) {

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 7a5b177..5f90060 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -170,6 +170,9 @@ public class LensQueryCommands extends BaseLensCommand {
         sb.append("Progress Message : ").append(status.getProgressMessage()).append("\n");
       }
     }
+    if (status.getQueueNumber() != 0) {
+      sb.append("Queue Number : ").append(status.getQueueNumber()).append("\n");
+    }
 
     if (status.getErrorMessage() != null) {
       sb.append("Error : ").append(status.getErrorMessage()).append("\n");

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
index f78b7c3..48a841b 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
@@ -89,6 +89,13 @@ public class DriverQueryStatus implements Serializable {
   private double progress = 0.0f;
 
   /**
+   * The running queue number.
+   */
+  @Getter
+  @Setter
+  private int queueNumber = 0;
+
+  /**
    * The state.
    */
   @Getter
@@ -167,7 +174,8 @@ public class DriverQueryStatus implements Serializable {
       break;
     }
 
-    return new QueryStatus(progress, qstate, statusMessage, isResultSetAvailable, progressMessage, errorMessage, null);
+    return new QueryStatus(progress, queueNumber, qstate, statusMessage, isResultSetAvailable, progressMessage,
+            errorMessage, null);
   }
 
   /**
@@ -178,8 +186,8 @@ public class DriverQueryStatus implements Serializable {
    * @return the query status
    */
   public static QueryStatus createQueryStatus(QueryStatus.Status state, DriverQueryStatus dstatus) {
-    return new QueryStatus(dstatus.progress, state, dstatus.statusMessage, dstatus.isResultSetAvailable,
-      dstatus.progressMessage, dstatus.errorMessage, null);
+    return new QueryStatus(dstatus.progress, dstatus.queueNumber, state, dstatus.statusMessage,
+            dstatus.isResultSetAvailable, dstatus.progressMessage, dstatus.errorMessage, null);
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
index 6cecf7e..c9b8854 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
@@ -204,7 +204,7 @@ public class FinishedLensQuery {
     qctx.setQueryHandle(QueryHandle.fromString(handle));
     qctx.setLaunchTime(this.startTime);
     qctx.setEndTime(getEndTime());
-    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, QueryStatus.Status.valueOf(getStatus()),
+    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, 0, QueryStatus.Status.valueOf(getStatus()),
         getErrorMessage() == null ? "" : getErrorMessage(), getResult() != null, null, null, null));
     qctx.getDriverStatus().setDriverStartTime(getDriverStartTime());
     qctx.getDriverStatus().setDriverFinishTime(getDriverEndTime());

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index beaa72f..0906b83 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -217,7 +217,7 @@ public class QueryContext extends AbstractQueryContext {
     super(userQuery, user, qconf, conf, drivers, mergeDriverConf);
     this.submissionTime = submissionTime;
     this.queryHandle = new QueryHandle(UUID.randomUUID());
-    this.status = new QueryStatus(0.0f, Status.NEW, "Query just got created", false, null, null, null);
+    this.status = new QueryStatus(0.0f, 0, Status.NEW, "Query just got created", false, null, null, null);
     this.priority = Priority.NORMAL;
     this.lensConf = qconf;
     this.conf = conf;

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
index 344ff10..4e3c95b 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
@@ -50,4 +50,10 @@ public interface ImmutableQueryCollection {
    * @return Count of existing queries
    */
   int getQueriesCount();
+
+  /**
+   *
+   * @return Index of a query within collection
+   */
+  int getQueryIndex(final QueryContext query);
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index c29a1ac..b23e0df 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -615,8 +615,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
       checkEstimatedQueriesState(query);
       QueryStatus oldStatus = query.getStatus();
-      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), QueryStatus.Status.LAUNCHED,
-          "Query is launched on driver", false, null, null, null);
+      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), query.getStatus().getQueueNumber(),
+        QueryStatus.Status.LAUNCHED, "Query is launched on driver", false, null, null, null);
       query.validateTransition(newStatus);
 
       // Check if we need to pass session's effective resources to selected driver
@@ -717,7 +717,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, FAILED, statusMsg, false, null, reason, lensErrorTO));
+    ctx.setStatus(new QueryStatus(0.0f, 0, FAILED, statusMsg, false, null, reason, lensErrorTO));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -731,7 +731,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    */
   private void setCancelledStatus(QueryContext ctx, String statusMsg) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, CANCELED, statusMsg, false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0f, 0, CANCELED, statusMsg, false, null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -765,7 +765,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
   void setSuccessState(QueryContext ctx) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(1.0f, SUCCESSFUL, "Query is successful!", ctx
+    ctx.setStatus(new QueryStatus(1.0f, 0, SUCCESSFUL, "Query is successful!", ctx
       .isResultAvailableInDriver(), null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
@@ -786,6 +786,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           log.info("Updating status for {}", ctx.getQueryHandle());
           try {
             ctx.getSelectedDriver().updateStatus(ctx);
+            ctx.getDriverStatus().setQueueNumber(launchedQueries.getQueryIndex(ctx));
             ctx.setStatus(ctx.getDriverStatus().toQueryStatus());
           } catch (LensException exc) {
             // Driver gave exception while updating status
@@ -946,7 +947,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             resultSets.remove(finished.getCtx().getQueryHandle());
           }
           fireStatusChangeEvent(finished.getCtx(),
-            new QueryStatus(1f, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
+            new QueryStatus(1f, 0, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
           log.info("Query purged: {}", finished.getCtx().getQueryHandle());
 
         } catch (LensException e) {
@@ -1700,7 +1701,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   private QueryHandle submitQuery(final QueryContext ctx) throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0, QUEUED, "Query is queued", false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0, 0, QUEUED, "Query is queued", false, null, null, null));
     queuedQueries.add(ctx);
     log.debug("Added to Queued Queries:{}", ctx.getQueryHandleString());
     allQueries.put(ctx.getQueryHandle(), ctx);

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
index e3505bb..bd27de8 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
@@ -138,6 +138,11 @@ public class DefaultEstimatedQueryCollection implements EstimatedQueryCollection
     return this.queries.getQueriesCount();
   }
 
+  @Override
+  public int getQueryIndex(QueryContext query) {
+    return this.queries.getQueryIndex(query);
+  }
+
   @VisibleForTesting
   void checkState(final QueryContext query) {
     Preconditions.checkState(query.getSelectedDriver() != null);

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
index f9e7701..0387cce 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
@@ -96,6 +96,26 @@ public class DefaultQueryCollection implements QueryCollection {
     return queries.size();
   }
 
+
+  /**
+   *  Since the collection is a linkedHashSet, the order of queries is always maintained.
+   * @param query
+   * @return
+   */
+  @Override
+  public int getQueryIndex(QueryContext query) {
+    Iterator iterator = queries.iterator();
+    int index = 1;
+    while (iterator.hasNext()) {
+      QueryContext queuedQuery = (QueryContext) iterator.next();
+      if (queuedQuery.getQueryHandle().equals(query.getQueryHandle())) {
+        return index;
+      }
+      index += 1;
+    }
+    return 0;
+  }
+
   private Collection<QueryContext> getQueriesCollectionForUser(final String user) {
 
     final Collection<QueryContext> userQueries = queriesByUser.getCollection(user);

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
index e6e777c..de0779a 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/MutableQueryCollection.java
@@ -62,4 +62,5 @@ public interface MutableQueryCollection {
    * @param queries
    */
   boolean removeAll(final Set<QueryContext> queries);
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
index cdbd2ad..5b80296 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
@@ -70,6 +70,11 @@ public class ThreadSafeEstimatedQueryCollection implements EstimatedQueryCollect
   }
 
   @Override
+  public synchronized int getQueryIndex(QueryContext query) {
+    return this.estimatedQueries.getQueryIndex(query);
+  }
+
+  @Override
   public synchronized boolean add(QueryContext query) {
     return this.estimatedQueries.add(query);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
index 7b43a38..4d5c7a1 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
@@ -72,4 +72,9 @@ public class ThreadSafeQueryCollection implements QueryCollection {
   public synchronized int getQueriesCount() {
     return this.queries.getQueriesCount();
   }
+
+  @Override
+  public synchronized int getQueryIndex(QueryContext query) {
+    return this.queries.getQueryIndex(query);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
index 7a81e83..f55094a 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
@@ -34,6 +34,7 @@ import org.testng.annotations.Test;
 public class DefaultQueryCollectionTest {
 
   private static final String MOCK_USER = "MockUserEmail";
+  private static final String MOCK_HANDLE = "0-0-0-0-";
 
   /* Note: Since verification of addition/removal required calling get methods,
   hence methods getQueriesCount and getQueries(user) are indirectly getting tested in these tests */
@@ -76,6 +77,28 @@ public class DefaultQueryCollectionTest {
   }
 
   @Test
+  public void testRemoveMethodMustChangeQueryIndices() {
+
+    /* Initialization */
+    final int noOfQueriesUsedInTest = 10;
+    QueryCollection queries = createQueriesInstanceWithQueryHandleStubbing(noOfQueriesUsedInTest, MOCK_HANDLE);
+
+    QueryContext completedQuery = getMockedQueryFromQueries(queries.getQueries(), MOCK_HANDLE, 4);
+    QueryContext runningQuery = getMockedQueryFromQueries(queries.getQueries(), MOCK_HANDLE, 5);
+
+    /* Execution */
+    queries.remove(completedQuery);
+
+     /* Verification 1: Verifies that queries were removed from queries list by calling getQueriesCount which gets
+    results from queries list */
+    assertEquals(queries.getQueriesCount(), 9);
+
+    /* Verification 2: Verifies that query index is decreased after removal of queries which were present before
+     them in the queries list */
+    assertEquals(queries.getQueryIndex(runningQuery), 4);
+  }
+
+  @Test
   public void testGetQueriesMustReturnCopyOfUnderlyingCollection() {
 
     /* Initialization */

http://git-wip-us.apache.org/repos/asf/lens/blob/2f22f60b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
index 51fcf00..63d1508 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
@@ -27,8 +27,10 @@ import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertTrue;
 
 import java.lang.reflect.Method;
+import java.util.Iterator;
 import java.util.Set;
 
+import org.apache.lens.api.query.QueryHandle;
 import org.apache.lens.server.api.query.QueryContext;
 
 import com.google.common.collect.Sets;
@@ -77,6 +79,34 @@ public class QueryCollectUtil {
     return new DefaultQueryCollection(mockQueries);
   }
 
+  public static QueryCollection createQueriesInstanceWithQueryHandleStubbing(final int reqNoOfMockQueries,
+    final String handlePrefix) {
+
+    Set<QueryContext> mockQueries = Sets.newLinkedHashSet();
+
+    for (int index = 1; index <= reqNoOfMockQueries; ++index) {
+      mockQueries.add(createQueryInstanceWithQueryHandleStubbing(handlePrefix, index));
+    }
+    return new DefaultQueryCollection(mockQueries);
+  }
+
+  public static QueryContext createQueryInstanceWithQueryHandleStubbing(String handlePrefix, int index) {
+    QueryContext mockQuery = mock(QueryContext.class);
+    when(mockQuery.getQueryHandle()).thenReturn(QueryHandle.fromString(handlePrefix + index));
+    return mockQuery;
+  }
+
+  public static QueryContext getMockedQueryFromQueries(Set<QueryContext> queries, String mockHandle, int index) {
+    Iterator iterator = queries.iterator();
+    while (iterator.hasNext()) {
+      QueryContext queuedQuery = (QueryContext) iterator.next();
+      if (queuedQuery.getQueryHandle().equals(QueryHandle.fromString(mockHandle + index))) {
+        return queuedQuery;
+      }
+    }
+    return null;
+  }
+
   public static QueryCollection stubMockQueryAndCreateQueriesInstance(final QueryContext mockQuery,
     final String mockUser) {
 


[28/50] [abbrv] lens git commit: LENS-113: Document how to document a feature in contributor guide

Posted by ra...@apache.org.
LENS-113: Document how to document a feature in contributor guide


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

Branch: refs/heads/current-release-line
Commit: d457dd0de755cfe46e9bb2b15ea837bdec5ff843
Parents: b72c760
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Wed Sep 23 11:42:31 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Wed Sep 23 11:42:31 2015 +0530

----------------------------------------------------------------------
 src/site/apt/developer/contribute.apt | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/d457dd0d/src/site/apt/developer/contribute.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/developer/contribute.apt b/src/site/apt/developer/contribute.apt
index ef3854a..6183b07 100644
--- a/src/site/apt/developer/contribute.apt
+++ b/src/site/apt/developer/contribute.apt
@@ -483,11 +483,34 @@ Developer Documentation : How to contribute to Apache Lens?
 
 ** Feature documentation
 
-  TODO
+  End users of Lens include :
 
-** Design and architecture documentation
+  * Querying users : mostly un-aware of system details, and un-aware of underlying data layout.
 
-  TODO
+  * Schema designer : Schema designer would understand the data model and come up with schema for their data.
+
+  * Server administrator : Lens server administrator understands the server setup, how multiple execution engines can be
+  added/removed and how to support multiple storage.
+
+  * Developer : Developers can develop new drivers, new features on server or client or anything to do with code.
+
+
+  Whenever a new feature is added to Lens, the developer should understand to whom the feature is applicable and put
+  it in proper menu - "User Menu" for Querying users and schema designers; "Admin Menu" for server administrators and
+  "Developer Menu" for developer related features.
+
+  The following details about the feature should be documented :
+
+  * The use case : Explaining Why the feature is required.
+
+  * The feature itself : What the feature is.
+
+  * How to enable the feature, if any.
+
+  * Who are the users of feature and who are not, if any.
+
+  The design documentation related to the feature can go in developer documentation or
+  {{{https://cwiki.apache.org/confluence/display/LENS/DesignDocs} Design docs}}.
 
 ** Confluence usage
 


[08/50] [abbrv] lens git commit: LENS-755 : Rename LogicalTableCrudCommand to ConceptualTableCrudCommand and PhysicalTableCrudCommand to LogicalTableCrudCommand

Posted by ra...@apache.org.
LENS-755 : Rename LogicalTableCrudCommand to ConceptualTableCrudCommand and PhysicalTableCrudCommand to LogicalTableCrudCommand


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/6efecda0
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/6efecda0
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/6efecda0

Branch: refs/heads/current-release-line
Commit: 6efecda0ed7a6717280eff3585612abac3940cdc
Parents: 86f251a
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Mon Aug 31 10:52:20 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Mon Aug 31 10:52:20 2015 +0530

----------------------------------------------------------------------
 .../commands/ConceptualTableCrudCommand.java    |  31 +++++
 .../lens/cli/commands/LensCubeCommands.java     |   2 +-
 .../cli/commands/LensDimensionCommands.java     |   2 +-
 .../commands/LensDimensionTableCommands.java    |   2 +-
 .../lens/cli/commands/LensFactCommands.java     |   2 +-
 .../cli/commands/LogicalTableCrudCommand.java   | 112 +++++++++++++++-
 .../cli/commands/PhysicalTableCrudCommand.java  | 131 -------------------
 7 files changed, 141 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/ConceptualTableCrudCommand.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/ConceptualTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/ConceptualTableCrudCommand.java
new file mode 100644
index 0000000..44876cf
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/ConceptualTableCrudCommand.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cli.commands;
+
+import org.apache.lens.cli.table.XFlattenedColumnTable;
+import org.apache.lens.cli.table.XJoinChainTable;
+
+public abstract class ConceptualTableCrudCommand<T> extends LensCRUDCommand<T> {
+  public String getAllFields(String table, boolean flattened) {
+    return new XFlattenedColumnTable(getClient().getQueryableFields(table, flattened), table).toString();
+  }
+  public String getAllJoinChains(String table) {
+    return new XJoinChainTable(getClient().getJoinChains(table)).toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
index cfee32f..0afdd61 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java
@@ -38,7 +38,7 @@ import lombok.NonNull;
 @Component
 @UserDocumentation(title = "OLAP Data cube metadata management",
   description = "These commands provide CRUD for cubes")
-public class LensCubeCommands extends LogicalTableCrudCommand<XCube> {
+public class LensCubeCommands extends ConceptualTableCrudCommand<XCube> {
 
   /**
    * Show cubes.

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
index 1f70337..cd7de55 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java
@@ -37,7 +37,7 @@ import lombok.NonNull;
  */
 @Component
 @UserDocumentation(title = "Dimension Management", description = "These commands provide CRUD for Dimensions")
-public class LensDimensionCommands extends LogicalTableCrudCommand<XDimension> {
+public class LensDimensionCommands extends ConceptualTableCrudCommand<XDimension> {
 
   /**
    * Show dimensions.

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
index 1759d9c..74efed9 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java
@@ -40,7 +40,7 @@ import lombok.NonNull;
 @Component
 @UserDocumentation(title = "Commands for Dimension Tables",
   description = "These commands provide CRUD for dimension tables, associated storages, and fact partitions")
-public class LensDimensionTableCommands extends PhysicalTableCrudCommand<XDimensionTable>
+public class LensDimensionTableCommands extends LogicalTableCrudCommand<XDimensionTable>
   implements CommandMarker {
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
index e2f1c50..6d7d9eb 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java
@@ -39,7 +39,7 @@ import lombok.NonNull;
 @Component
 @UserDocumentation(title = "Management of Facts",
   description = "These command provide CRUD for facts, associated storages, and fact partitions")
-public class LensFactCommands extends PhysicalTableCrudCommand<XFactTable> {
+public class LensFactCommands extends LogicalTableCrudCommand<XFactTable> {
 
   /**
    * Show facts.

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
index 3c78e43..a04d5c8 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
@@ -18,14 +18,114 @@
  */
 package org.apache.lens.cli.commands;
 
-import org.apache.lens.cli.table.XFlattenedColumnTable;
-import org.apache.lens.cli.table.XJoinChainTable;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.lens.api.APIResult;
+import org.apache.lens.api.metastore.XPartition;
+import org.apache.lens.api.metastore.XStorageTableElement;
+
+import com.google.common.base.Joiner;
 
 public abstract class LogicalTableCrudCommand<T> extends LensCRUDCommand<T> {
-  public String getAllFields(String table, boolean flattened) {
-    return new XFlattenedColumnTable(getClient().getQueryableFields(table, flattened), table).toString();
+  public String showAll(String filter) {
+    List<String> all = getAll(filter);
+    if (all == null || all.isEmpty()) {
+      return "No " + getSingleObjectName() + " found" + (filter == null ? "" : " for " + filter);
+    }
+    return Joiner.on("\n").join(all);
+  }
+
+  public String showAllStorages(String tableName) {
+    String sep = "";
+    StringBuilder sb = new StringBuilder();
+    List<String> storages = getAllStorages(tableName);
+    if (storages != null) {
+      for (String storage : storages) {
+        if (!storage.isEmpty()) {
+          sb.append(sep).append(storage);
+          sep = "\n";
+        }
+      }
+    }
+    String ret = sb.toString();
+    return ret.isEmpty() ? "No storage found for " + tableName : ret;
+  }
+
+  public String addStorage(String tableName, File path) {
+    return doAddStorage(tableName, getValidPath(path, false, true)).toString().toLowerCase();
+  }
+
+  public String getStorage(String tableName, String storage) {
+    try {
+      return formatJson(mapper.writer(pp).writeValueAsString(readStorage(tableName, storage)));
+    } catch (IOException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  public String dropStorage(String tableName, String storageName) {
+    return doDropStorage(tableName, storageName).toString().toLowerCase();
   }
-  public String getAllJoinChains(String table) {
-    return new XJoinChainTable(getClient().getJoinChains(table)).toString();
+
+  public String dropAllStorages(String tableName) {
+    return doDropAllStorages(tableName).toString();
   }
+
+  public String getAllPartitions(String tableName, String storageName, String filter) {
+    try {
+      return formatJson(mapper.writer(pp).writeValueAsString(readAllPartitions(tableName, storageName, filter)));
+    } catch (IOException e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+
+  public String addPartition(String tableName, String storageName, File path) {
+    return doAddPartition(tableName, storageName,
+        getValidPath(path, false, true)).toString().toLowerCase();
+  }
+
+  public String updatePartition(String tableName, String storageName, File path) {
+    return doUpdatePartition(tableName, storageName, getValidPath(path, false, true)).toString()
+      .toLowerCase();
+  }
+
+  public String addPartitions(String tableName, String storageName, String path) {
+    return doAddPartitions(tableName, storageName,
+        getValidPath(new File(path), false, true)).toString().toLowerCase();
+  }
+
+  public String updatePartitions(String tableName, String storageName, String path) {
+    return doUpdatePartitions(tableName, storageName,
+        getValidPath(new File(path), false, true)).toString().toLowerCase();
+  }
+
+  public String dropPartitions(String tableName, String storageName, String filter) {
+    return doDropPartitions(tableName, storageName, filter).toString().toLowerCase();
+  }
+
+  protected abstract List<String> getAll(String filter);
+
+  public abstract List<String> getAllStorages(String name);
+
+  public abstract APIResult doAddStorage(String name, String path);
+
+  protected abstract XStorageTableElement readStorage(String tableName, String storage);
+
+  public abstract APIResult doDropStorage(String tableName, String storageName);
+
+  public abstract APIResult doDropAllStorages(String name);
+
+  protected abstract List<XPartition> readAllPartitions(String tableName, String storageName, String filter);
+
+  protected abstract APIResult doAddPartition(String tableName, String storageName, String path);
+
+  protected abstract APIResult doAddPartitions(String tableName, String storageName, String path);
+
+  protected abstract APIResult doDropPartitions(String tableName, String storageName, String filter);
+
+  protected abstract APIResult doUpdatePartition(String tableName, String storageName, String validPath);
+
+  protected abstract APIResult doUpdatePartitions(String tableName, String storageName, String validPath);
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/6efecda0/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java
deleted file mode 100644
index a1ccec6..0000000
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.lens.cli.commands;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.lens.api.APIResult;
-import org.apache.lens.api.metastore.XPartition;
-import org.apache.lens.api.metastore.XStorageTableElement;
-
-import com.google.common.base.Joiner;
-
-public abstract class PhysicalTableCrudCommand<T> extends LensCRUDCommand<T> {
-  public String showAll(String filter) {
-    List<String> all = getAll(filter);
-    if (all == null || all.isEmpty()) {
-      return "No " + getSingleObjectName() + " found" + (filter == null ? "" : " for " + filter);
-    }
-    return Joiner.on("\n").join(all);
-  }
-
-  public String showAllStorages(String tableName) {
-    String sep = "";
-    StringBuilder sb = new StringBuilder();
-    List<String> storages = getAllStorages(tableName);
-    if (storages != null) {
-      for (String storage : storages) {
-        if (!storage.isEmpty()) {
-          sb.append(sep).append(storage);
-          sep = "\n";
-        }
-      }
-    }
-    String ret = sb.toString();
-    return ret.isEmpty() ? "No storage found for " + tableName : ret;
-  }
-
-  public String addStorage(String tableName, File path) {
-    return doAddStorage(tableName, getValidPath(path, false, true)).toString().toLowerCase();
-  }
-
-  public String getStorage(String tableName, String storage) {
-    try {
-      return formatJson(mapper.writer(pp).writeValueAsString(readStorage(tableName, storage)));
-    } catch (IOException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  public String dropStorage(String tableName, String storageName) {
-    return doDropStorage(tableName, storageName).toString().toLowerCase();
-  }
-
-  public String dropAllStorages(String tableName) {
-    return doDropAllStorages(tableName).toString();
-  }
-
-  public String getAllPartitions(String tableName, String storageName, String filter) {
-    try {
-      return formatJson(mapper.writer(pp).writeValueAsString(readAllPartitions(tableName, storageName, filter)));
-    } catch (IOException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  public String addPartition(String tableName, String storageName, File path) {
-    return doAddPartition(tableName, storageName,
-        getValidPath(path, false, true)).toString().toLowerCase();
-  }
-
-  public String updatePartition(String tableName, String storageName, File path) {
-    return doUpdatePartition(tableName, storageName, getValidPath(path, false, true)).toString()
-      .toLowerCase();
-  }
-
-  public String addPartitions(String tableName, String storageName, String path) {
-    return doAddPartitions(tableName, storageName,
-        getValidPath(new File(path), false, true)).toString().toLowerCase();
-  }
-
-  public String updatePartitions(String tableName, String storageName, String path) {
-    return doUpdatePartitions(tableName, storageName,
-        getValidPath(new File(path), false, true)).toString().toLowerCase();
-  }
-
-  public String dropPartitions(String tableName, String storageName, String filter) {
-    return doDropPartitions(tableName, storageName, filter).toString().toLowerCase();
-  }
-
-  protected abstract List<String> getAll(String filter);
-
-  public abstract List<String> getAllStorages(String name);
-
-  public abstract APIResult doAddStorage(String name, String path);
-
-  protected abstract XStorageTableElement readStorage(String tableName, String storage);
-
-  public abstract APIResult doDropStorage(String tableName, String storageName);
-
-  public abstract APIResult doDropAllStorages(String name);
-
-  protected abstract List<XPartition> readAllPartitions(String tableName, String storageName, String filter);
-
-  protected abstract APIResult doAddPartition(String tableName, String storageName, String path);
-
-  protected abstract APIResult doAddPartitions(String tableName, String storageName, String path);
-
-  protected abstract APIResult doDropPartitions(String tableName, String storageName, String filter);
-
-  protected abstract APIResult doUpdatePartition(String tableName, String storageName, String validPath);
-
-  protected abstract APIResult doUpdatePartitions(String tableName, String storageName, String validPath);
-}


[45/50] [abbrv] lens git commit: LENS-446: Remove server params from session and driver configurations

Posted by ra...@apache.org.
LENS-446: Remove server params from session and driver configurations


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/7080b76c
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/7080b76c
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/7080b76c

Branch: refs/heads/current-release-line
Commit: 7080b76c63a82e09b5d42c2d2b7458f80b1085f8
Parents: 02760a3
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Thu Oct 8 15:14:57 2015 +0530
Committer: Raju Bairishetti <ra...@im0933-x0.corp.inmobi.com>
Committed: Thu Oct 8 15:14:57 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/server/LensApplication.java |  2 +-
 .../org/apache/lens/server/LensServerConf.java  | 24 ++++++++++++++++----
 .../server/query/QueryExecutionServiceImpl.java |  2 +-
 .../lens/server/session/LensSessionImpl.java    | 23 ++++++++++++++-----
 .../lens/server/query/TestQueryService.java     |  4 ++++
 .../server/session/TestSessionResource.java     |  9 +++++++-
 6 files changed, 50 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/main/java/org/apache/lens/server/LensApplication.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/LensApplication.java b/lens-server/src/main/java/org/apache/lens/server/LensApplication.java
index a446ab6..71ff9ea 100644
--- a/lens-server/src/main/java/org/apache/lens/server/LensApplication.java
+++ b/lens-server/src/main/java/org/apache/lens/server/LensApplication.java
@@ -38,7 +38,7 @@ import lombok.extern.slf4j.Slf4j;
 public class LensApplication extends Application {
 
   /** The conf. */
-  public static final Configuration CONF = LensServerConf.getConf();
+  public static final Configuration CONF = LensServerConf.getHiveConf();
 
   @Override
   public Set<Class<?>> getClasses() {

http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/main/java/org/apache/lens/server/LensServerConf.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/LensServerConf.java b/lens-server/src/main/java/org/apache/lens/server/LensServerConf.java
index 4d333c6..6db720d 100644
--- a/lens-server/src/main/java/org/apache/lens/server/LensServerConf.java
+++ b/lens-server/src/main/java/org/apache/lens/server/LensServerConf.java
@@ -18,6 +18,11 @@
  */
 package org.apache.lens.server;
 
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.lens.server.api.LensConfConstants;
+
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hive.conf.HiveConf;
 
@@ -32,13 +37,22 @@ public final class LensServerConf {
   private static final class ConfHolder {
     public static final HiveConf HIVE_CONF = new HiveConf();
     // configuration object which does not load defaults and loads only lens*.xml files.
-    public static final Configuration CONF = new Configuration(false);
+    // and removes any server specific configuration, that should not be passed to drivers
+    private static final Configuration OVERRIDING_CONF_FOR_DRIVER = new Configuration(false);
 
     static {
       HIVE_CONF.addResource("lensserver-default.xml");
       HIVE_CONF.addResource("lens-site.xml");
-      CONF.addResource("lensserver-default.xml");
-      CONF.addResource("lens-site.xml");
+      Configuration conf = new Configuration(false);
+      conf.addResource("lens-site.xml");
+      Iterator<Map.Entry<String, String>> confItr = conf.iterator();
+      while (confItr.hasNext()) {
+        Map.Entry<String, String> prop = confItr.next();
+        if (!prop.getKey().startsWith(LensConfConstants.SERVER_PFX)) {
+          OVERRIDING_CONF_FOR_DRIVER.set(prop.getKey(), prop.getValue());
+        }
+      }
+
     }
   }
 
@@ -57,8 +71,8 @@ public final class LensServerConf {
    *
    * @return the conf
    */
-  public static Configuration getConf() {
-    return ConfHolder.CONF;
+  public static Configuration getConfForDrivers() {
+    return ConfHolder.OVERRIDING_CONF_FOR_DRIVER;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 73179e1..d57812f 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -338,7 +338,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       for (Class<?> driverClass : driverClasses) {
         try {
           LensDriver driver = (LensDriver) driverClass.newInstance();
-          driver.configure(LensServerConf.getConf());
+          driver.configure(LensServerConf.getConfForDrivers());
           if (driver instanceof HiveDriver) {
             driver.registerDriverEventListener(driverEventListener);
           }

http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/main/java/org/apache/lens/server/session/LensSessionImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/session/LensSessionImpl.java b/lens-server/src/main/java/org/apache/lens/server/session/LensSessionImpl.java
index d0677cc..9d8f198 100644
--- a/lens-server/src/main/java/org/apache/lens/server/session/LensSessionImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/session/LensSessionImpl.java
@@ -65,7 +65,7 @@ public class LensSessionImpl extends HiveSessionImpl {
   private long sessionTimeout;
 
   /** The conf. */
-  private Configuration conf = createDefaultConf();
+  private Configuration conf = new Configuration(createDefaultConf());
 
   /**
    * Keep track of DB static resources which failed to be added to this session
@@ -102,16 +102,27 @@ public class LensSessionImpl extends HiveSessionImpl {
     persistInfo.setSessionConf(sessionConf);
   }
 
+  private static Configuration sessionDefaultConfig;
   /**
    * Creates the default conf.
    *
    * @return the configuration
    */
-  public static Configuration createDefaultConf() {
-    Configuration conf = new Configuration(false);
-    conf.addResource("lenssession-default.xml");
-    conf.addResource("lens-site.xml");
-    return conf;
+  public static synchronized Configuration createDefaultConf() {
+    if (sessionDefaultConfig == null) {
+      Configuration conf = new Configuration(false);
+      conf.addResource("lenssession-default.xml");
+      conf.addResource("lens-site.xml");
+      sessionDefaultConfig = new Configuration(false);
+      Iterator<Map.Entry<String, String>> confItr = conf.iterator();
+      while (confItr.hasNext()) {
+        Map.Entry<String, String> prop = confItr.next();
+        if (!prop.getKey().startsWith(LensConfConstants.SERVER_PFX)) {
+          sessionDefaultConfig.set(prop.getKey(), prop.getValue());
+        }
+      }
+    }
+    return sessionDefaultConfig;
   }
 
   /** The default hive session conf. */

http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index ea75ffb..6218882 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -1167,6 +1167,8 @@ public class TestQueryService extends LensJerseyTest {
     assertNull(conf.get("hive.metastore.warehouse.dir"));
     // core default should not be loaded
     assertNull(conf.get("fs.default.name"));
+    // server configuration should not set
+    assertNull(conf.get("lens.server.persist.location"));
 
     // Test server config. Hive configs overriden should be set
     assertFalse(Boolean.parseBoolean(queryService.getHiveConf().get("hive.server2.log.redirection.enabled")));
@@ -1202,6 +1204,8 @@ public class TestQueryService extends LensJerseyTest {
       assertEquals(dconf.get("lens.driver.test.key"), "set");
       // core default should not be loaded
       assertNull(dconf.get("fs.default.name"));
+      // server configuration should not set
+      assertNull(dconf.get("lens.server.persist.location"));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/7080b76c/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java b/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
index 8fffbc9..3055ce5 100644
--- a/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
+++ b/lens-server/src/test/java/org/apache/lens/server/session/TestSessionResource.java
@@ -169,7 +169,14 @@ public class TestSessionResource extends LensJerseyTest {
     System.out.println("Session params:" + sessionParams.getElements());
     Assert.assertEquals(sessionParams.getElements().size(), 1);
     Assert.assertTrue(sessionParams.getElements().contains("my.conf=myvalue"));
-
+    // get server params on session
+    try {
+      paramtarget.queryParam("sessionid", handle).queryParam("key", "lens.server.persist.location").request()
+        .get(StringList.class);
+      Assert.fail("Expected 404");
+    } catch (Exception ne) {
+      Assert.assertTrue(ne instanceof NotFoundException);
+    }
     // get all params verbose
     sessionParams = paramtarget.queryParam("sessionid", handle).queryParam("verbose", true).request()
       .get(StringList.class);


[49/50] [abbrv] lens git commit: LENS-782: UI support for the saved, parametrized query feature

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/QueryResultsComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryResultsComponent.js b/lens-ui/app/components/QueryResultsComponent.js
index 6e4b8c2..01f0e30 100644
--- a/lens-ui/app/components/QueryResultsComponent.js
+++ b/lens-ui/app/components/QueryResultsComponent.js
@@ -19,7 +19,7 @@
 
 import React from 'react';
 
-import Loader from '../components/LoaderComponent';
+import Loader from './LoaderComponent';
 import AdhocQueryStore from '../stores/AdhocQueryStore';
 import UserStore from '../stores/UserStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
@@ -31,12 +31,10 @@ function getResults (props) {
   let secretToken = UserStore.getUserDetails().secretToken;
 
   if (props.query.category) {
-
     // fetch either running or completed results
     AdhocQueryActions
       .getQueries(secretToken, email, { state: props.query.category });
   } else {
-
     // fetch all
     AdhocQueryActions.getQueries(secretToken, email);
   }
@@ -77,12 +75,12 @@ class QueryResults extends React.Component {
         return queryMap[b].submissionTime - queryMap[a].submissionTime;
       })
       .map((queryHandle) => {
-      let query = queryMap[queryHandle];
+        let query = queryMap[queryHandle];
 
-      return (
-        <QueryPreview key={query.queryHandle.handleId} {...query} />
-      );
-    }); // end of map
+        return (
+          <QueryPreview key={query.queryHandle.handleId} {...query} />
+        );
+      }); // end of map
 
     // FIXME find a better way to do it.
     // show a loader when queries are empty, or no queries.
@@ -93,9 +91,9 @@ class QueryResults extends React.Component {
     let queriesLength = Object.keys(this.state.queries).length;
 
     if (!queriesLength && !this.state.queriesReceived) {
-      queries = <Loader size="8px" margin="2px" />;
+      queries = <Loader size='8px' margin='2px' />;
     } else if (!queriesLength && this.state.queriesReceived) {
-      queries = <div className="alert alert-danger">
+      queries = <div className='alert alert-danger'>
         <strong>Sorry</strong>, there were no queries to be shown.
       </div>;
     }
@@ -105,9 +103,8 @@ class QueryResults extends React.Component {
         <div style={{border: '1px solid #dddddd', borderRadius: '4px',
           padding: '0px 8px 8px 8px'}}>
           <h3 style={{margin: '8px 10px'}}>Results</h3>
-          <hr style={{marginTop: '6px' }}/>
-          <div style={{overflowY: 'auto',
-            maxHeight: this.props.toggleQueryBox ? '300px': '600px'}}>
+          <hr style={{marginTop: '6px'}}/>
+          <div>
             {queries}
           </div>
         </div>
@@ -116,7 +113,7 @@ class QueryResults extends React.Component {
   }
 
   _onChange () {
-    this.setState({ queries: getQueries(), queriesReceived: true});
+    this.setState({queries: getQueries(), queriesReceived: true});
   }
 }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/RequireAuthenticationComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/RequireAuthenticationComponent.js b/lens-ui/app/components/RequireAuthenticationComponent.js
index 9a755b0..7b1e956 100644
--- a/lens-ui/app/components/RequireAuthenticationComponent.js
+++ b/lens-ui/app/components/RequireAuthenticationComponent.js
@@ -29,9 +29,9 @@ let RequireAuthentication = (Component) => {
     }
 
     render () {
-      return <Component {...this.props} />
+      return <Component {...this.props} />;
     }
-  }
+  };
 };
 
 export default RequireAuthentication;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/SavedQueriesComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/SavedQueriesComponent.js b/lens-ui/app/components/SavedQueriesComponent.js
new file mode 100644
index 0000000..378fa13
--- /dev/null
+++ b/lens-ui/app/components/SavedQueriesComponent.js
@@ -0,0 +1,180 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import SavedQueryStore from '../stores/SavedQueryStore';
+import UserStore from '../stores/UserStore';
+import Loader from './LoaderComponent';
+import SavedQueryPreview from './SavedQueryPreviewComponent';
+
+class SavedQueries extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {
+      loading: true,
+      savedQueries: null,
+      page: null,
+      totalPages: null
+    };
+
+    this._onChange = this._onChange.bind(this);
+    this.prev = this.prev.bind(this);
+    this.next = this.next.bind(this);
+    this._getPaginatedSavedQueries = this._getPaginatedSavedQueries.bind(this);
+
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let user = UserStore.getUserDetails().email;
+    AdhocQueryActions.getSavedQueries(secretToken, user);
+  }
+
+  componentDidMount () {
+    SavedQueryStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    SavedQueryStore.removeChangeListener(this._onChange);
+  }
+
+  render () {
+    let loading = this.state.loading ? <Loader size='4px' margin='2px'/> : null;
+
+    let queries = !this.state.savedQueries ? null :
+      Object.keys(this.state.savedQueries).map(queryId => {
+        return <SavedQueryPreview key={'saved|' + queryId}
+          query={this.state.savedQueries[queryId]} />;
+      });
+
+    // no saved queries
+    if (!this.state.loading && !queries) {
+      queries = (<div className='alert-danger' style={{padding: '8px 5px'}}>
+          <strong>Sorry, we couldn&#39;t find any saved queries.</strong>
+        </div>);
+    }
+
+    if (!this.state.loading && this.state.totalPages == 0) {
+      queries = (<div className='alert-danger' style={{padding: '8px 5px'}}>
+          <strong>You&#39;ve not saved any query.</strong>
+        </div>);
+    }
+
+    var pagination = (
+      <div className='pull-right'>
+        <button onClick={this.prev}
+          className='btn btn-link glyphicon glyphicon-triangle-left'>
+        </button>
+          <small>
+            { this.state.page && this.state.totalPages &&
+              (this.state.page + ' of ' + this.state.totalPages)
+            }
+          </small>
+        <button onClick={this.next}
+          className='btn btn-link glyphicon glyphicon-triangle-right'>
+        </button>
+      </div>
+    );
+
+    return (
+      <section>
+        <div style={{border: '1px solid #dddddd', borderRadius: '4px',
+          padding: '0px 8px 8px 8px'}}>
+          <h3 style={{margin: '8px 10px'}}>
+            Saved Queries
+            {pagination}
+          </h3>
+          <hr style={{marginTop: '6px'}}/>
+          <div>
+            {loading}
+            {queries}
+          </div>
+        </div>
+      </section>
+    );
+  }
+
+  prev () {
+    if (this.state.page > 1) this._onChange(this.state.page - 1);
+  }
+
+  next () {
+    if (this.state.page < this.state.totalPages) {
+      this._onChange(this.state.page + 1);
+    }
+  }
+
+  _onChange (page) {
+    // done to filter success/error messages from store
+    if (typeof page === 'object') page = this.state.page;
+
+    var PAGE_SIZE = 10;
+    page = page || this.state.page || 1;
+    var state = {
+      savedQueries: this._getPaginatedSavedQueries(page, PAGE_SIZE),
+      page: page,
+      totalPages: Math.ceil(SavedQueryStore.getTotalRecords() / PAGE_SIZE)
+    };
+    state.loading = !!(!state.savedQueries && state.totalPages);
+    this.setState(state);
+  }
+
+  _getPaginatedSavedQueries (pageNumber, pageSize) {
+    if (!pageNumber && !pageSize) return;
+
+    var token = UserStore.getUserDetails().secretToken;
+    var email = UserStore.getUserDetails().email;
+    var savedQueries = SavedQueryStore.getSavedQueries();
+    var savedQueriesLength = savedQueries && Object.keys(savedQueries).length;
+    var totalQueries = SavedQueryStore.getTotalRecords();
+    var relevantSavedQueries = null;
+    var startIndex = (pageNumber - 1) * pageSize;
+    if (savedQueriesLength > startIndex) {
+      relevantSavedQueries = Object.keys(savedQueries)
+        .slice(startIndex, startIndex + pageSize);
+      if ((totalQueries != savedQueriesLength) && (relevantSavedQueries.length < pageSize) && totalQueries) {
+        // call backend
+        AdhocQueryActions.getSavedQueries(token, email, {
+          offset: startIndex,
+          pageSize: pageSize
+        });
+
+        this.setState({loading: true});
+      }
+    } else {
+      // trigger action
+      if (!totalQueries) return;
+
+      AdhocQueryActions.getSavedQueries(token, email, {
+        offset: startIndex,
+        pageSize: pageSize
+      });
+
+      this.setState({loading: true});
+    }
+
+    var filteredQueries = relevantSavedQueries && relevantSavedQueries.map(id => {
+      return savedQueries[id];
+    });
+
+    return filteredQueries;
+  }
+
+}
+
+export default SavedQueries;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/SavedQueryPreviewComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/SavedQueryPreviewComponent.js b/lens-ui/app/components/SavedQueryPreviewComponent.js
new file mode 100644
index 0000000..4f9459a
--- /dev/null
+++ b/lens-ui/app/components/SavedQueryPreviewComponent.js
@@ -0,0 +1,136 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { Link } from 'react-router';
+import CodeMirror from 'codemirror';
+import 'codemirror/mode/sql/sql.js';
+import 'codemirror/addon/runmode/runmode.js';
+
+import QueryParamRowComponent from './QueryParamRowComponent';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import UserStore from '../stores/UserStore';
+
+class SavedQueryPreview extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = { showDetail: false, queryParams: {} };
+    this.toggleQueryDetails = this.toggleQueryDetails.bind(this);
+    this.runSavedQuery = this.runSavedQuery.bind(this);
+    this.update = this.update.bind(this);
+    this.props.query && this.props.query.parameters.forEach(param => {
+      this.state.queryParams[param.name] = param;
+    });
+  }
+
+  render () {
+    let query = this.props.query;
+
+    if (!query.query) return null;
+
+    // code below before the return prepares the data to render, turning out
+    // crude properties to glazed, garnished ones e.g. formatting of query
+    let codeTokens = [];
+
+    CodeMirror
+      .runMode(query.query,
+        'text/x-mysql', function (text, style) {
+        // this method is called for every token and gives the
+        // token and style class for it.
+        codeTokens.push(<span className={'cm-' + style}>{text}</span>);
+      });
+
+    let params = query && query.parameters.map(param => {
+      return <QueryParamRowComponent param={param} entryMode={true}
+        updateParam={this.update}/>;
+    });
+
+    let paramsTable = !params.length ? null :
+      (<table className='table table-striped table-condensed'>
+        <thead>
+          <tr><th>Param</th><th>Display Name</th><th>Data Type</th>
+          <th>Collection Type</th><th>Value</th></tr>
+        </thead>
+        <tbody>
+          {params}
+        </tbody>
+      </table>);
+
+    return (
+      <section ref='preview'>
+        <div className='panel panel-default'>
+          <div className='panel-heading blue-header' style={{cursor: 'pointer', padding: '2px 8px'}}
+            onClick={this.toggleQueryDetails}>
+            <h5 className='panel-title' style={{marginBottom: '4px'}}>
+              {query.name || 'Unnamed Query'}
+            </h5>
+            <small className='italics'>
+              { query.description || 'No description available' }
+            </small>
+          </div>
+
+          {this.state.showDetail && (
+            <div className='panel-body' style={{borderTop: '1px solid #cccccc',
+              padding: '0px'}} key={'preview' + query.id}>
+              <pre className='cm-s-default' style={{
+                border: '0px', marginBottom: '0px'}}>
+                {codeTokens}
+
+                <Link to='query' query={{savedquery: query.id}}
+                  className='btn btn-default pull-right'>
+                  <i className='fa fa-pencil fa-lg'></i>
+                </Link>
+                <button className='btn btn-default pull-right' onClick={this.runSavedQuery}>
+                  <i className='fa fa-play fa-lg'></i>
+                </button>
+              </pre>
+
+              {paramsTable}
+            </div>
+          )}
+        </div>
+      </section>
+    );
+  }
+
+  toggleQueryDetails () {
+    this.setState({ showDetail: !this.state.showDetail });
+  }
+
+  update (param) {
+    this.state.queryParams[param.name] = param.param;
+  }
+
+  runSavedQuery () {
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let parameters = Object.keys(this.state.queryParams).map(name => {
+      let object = {};
+      object[name] = this.state.queryParams[name].defaultValue;
+      return object;
+    });
+    AdhocQueryActions.runSavedQuery(secretToken, this.props.query.id, parameters);
+  }
+}
+
+SavedQueryPreview.propTypes = {
+  query: React.PropTypes.object,
+  params: React.PropTypes.object
+};
+
+export default SavedQueryPreview;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/SidebarComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/SidebarComponent.js b/lens-ui/app/components/SidebarComponent.js
index dcc8737..37a2c59 100644
--- a/lens-ui/app/components/SidebarComponent.js
+++ b/lens-ui/app/components/SidebarComponent.js
@@ -24,7 +24,7 @@ import Database from './DatabaseComponent';
 import QueryOperations from './QueryOperationsComponent';
 
 class Sidebar extends React.Component {
-  render() {
+  render () {
     return (
       <section>
         <QueryOperations />
@@ -33,6 +33,6 @@ class Sidebar extends React.Component {
       </section>
     );
   }
-};
+}
 
 export default Sidebar;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/TableSchemaComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/TableSchemaComponent.js b/lens-ui/app/components/TableSchemaComponent.js
index 67dc25a..7abab95 100644
--- a/lens-ui/app/components/TableSchemaComponent.js
+++ b/lens-ui/app/components/TableSchemaComponent.js
@@ -22,7 +22,7 @@ import React from 'react';
 import TableStore from '../stores/TableStore';
 import UserStore from '../stores/UserStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
-import Loader from '../components/LoaderComponent';
+import Loader from './LoaderComponent';
 
 function getTable (tableName, database) {
   let tables = TableStore.getTables(database);
@@ -71,15 +71,14 @@ class TableSchema extends React.Component {
   render () {
     let schemaSection = null;
 
-
     if (this.state.table && !this.state.table.isLoaded) {
-      schemaSection = <Loader size="8px" margin="2px" />;
+      schemaSection = <Loader size='8px' margin='2px' />;
     } else {
-      schemaSection = (<div className="row">
-          <div className="table-responsive">
-            <table className="table table-striped">
+      schemaSection = (<div className='row'>
+          <div className='table-responsive'>
+            <table className='table table-striped'>
               <thead>
-              <caption className="bg-primary text-center">Columns</caption>
+              <caption className='bg-primary text-center'>Columns</caption>
                 <tr><th>Name</th><th>Type</th><th>Description</th></tr>
               </thead>
               <tbody>
@@ -91,8 +90,9 @@ class TableSchema extends React.Component {
                         <td>{col.type}</td>
                         <td>{col.comment || 'No description available'}</td>
                       </tr>
-                    )
-                })}
+                    );
+                  })
+                }
               </tbody>
             </table>
           </div>
@@ -101,16 +101,15 @@ class TableSchema extends React.Component {
 
     return (
       <section>
-        <div className="panel panel-default">
-          <div className="panel-heading">
-            <h3 className="panel-title">Schema Details: &nbsp;
-              <strong className="text-primary">
+        <div className='panel panel-default'>
+          <div className='panel-heading'>
+            <h3 className='panel-title'>Schema Details: &nbsp;
+              <strong className='text-primary'>
                  {this.props.query.database}.{this.props.params.tableName}
               </strong>
             </h3>
           </div>
-          <div className="panel-body" style={{overflowY: 'auto',
-            maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+          <div className='panel-body'>
             {schemaSection}
           </div>
         </div>
@@ -128,4 +127,9 @@ class TableSchema extends React.Component {
   }
 }
 
+TableSchema.propTypes = {
+  query: React.PropTypes.object,
+  params: React.PropTypes.object
+};
+
 export default TableSchema;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/components/TableTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/TableTreeComponent.js b/lens-ui/app/components/TableTreeComponent.js
index 026e443..59965d4 100644
--- a/lens-ui/app/components/TableTreeComponent.js
+++ b/lens-ui/app/components/TableTreeComponent.js
@@ -21,12 +21,11 @@ import React from 'react';
 import TreeView from 'react-treeview';
 import { Link } from 'react-router';
 import 'react-treeview/react-treeview.css';
-import ClassNames from 'classnames';
 
 import TableStore from '../stores/TableStore';
 import AdhocQueryActions from '../actions/AdhocQueryActions';
 import UserStore from '../stores/UserStore';
-import Loader from '../components/LoaderComponent';
+import Loader from './LoaderComponent';
 import '../styles/css/tree.css';
 
 let filterString = '';
@@ -39,8 +38,7 @@ function getState (page, filterString, database) {
 }
 
 function getTables (page, filterString, database) {
-
-  // get all the tables
+  // get all the native tables
   let tables = TableStore.getTables(database);
   let pageSize = 10;
   let allTables;
@@ -49,11 +47,9 @@ function getTables (page, filterString, database) {
   let pageTables;
 
   if (!filterString) {
-
     // no need for filtering
     allTables = Object.keys(tables);
   } else {
-
     // filter
     allTables = Object.keys(tables).map(name => {
       if (name.match(filterString)) return name;
@@ -67,7 +63,7 @@ function getTables (page, filterString, database) {
   });
 
   return {
-    totalPages: Math.ceil(allTables.length/pageSize),
+    totalPages: Math.ceil(allTables.length / pageSize),
     tables: pageTables
   };
 }
@@ -123,20 +119,20 @@ class TableTree extends React.Component {
 
     // construct tree
     tableTree = this.state.tables.map(table => {
-      let label = (<Link to="tableschema" params={{tableName: table.name}}
+      let label = (<Link to='tableschema' params={{tableName: table.name}}
         title={table.name} query={{database: this.props.database}}>
           {table.name}</Link>);
       return (
         <TreeView key={table.name} nodeLabel={label}
-          defaultCollapsed={true}>
+          defaultCollapsed={!table.isLoaded}>
 
           {table.isLoaded ? table.columns.map(col => {
             return (
-              <div className="treeNode" key={name + '|' + col.name}>
+              <div className='treeNode' key={table.name + '|' + col.name}>
                 {col.name} ({col.type})
               </div>
             );
-          }) : <Loader size="4px" margin="2px" />}
+          }) : <Loader size='4px' margin='2px' />}
 
         </TreeView>
       );
@@ -144,42 +140,41 @@ class TableTree extends React.Component {
 
     // show a loader when tree is loading
     if (this.state.loading) {
-      tableTree = <Loader size="4px" margin="2px" />;
+      tableTree = <Loader size='4px' margin='2px' />;
     } else if (!this.state.tables.length) {
-      tableTree = (<div className="alert-danger" style={{padding: '8px 5px'}}>
-          <strong>Sorry, we couldn&#39;t find any tables.</strong>
+      tableTree = (<div className='alert-danger' style={{padding: '8px 5px'}}>
+          <strong>Sorry, we couldn&#39;t find any.</strong>
         </div>);
     }
 
     let pagination = this.state.tables.length ?
       (
         <div>
-          <div className="text-center">
-            <button className="btn btn-link glyphicon glyphicon-triangle-left page-back"
+          <div className='text-center'>
+            <button className='btn btn-link glyphicon glyphicon-triangle-left page-back'
               onClick={this.prevPage}>
             </button>
             <span>{this.state.page} of {this.state.totalPages}</span>
-            <button className="btn btn-link glyphicon glyphicon-triangle-right page-next"
+            <button className='btn btn-link glyphicon glyphicon-triangle-right page-next'
               onClick={this.nextPage}>
             </button>
           </div>
         </div>
-      ) :
-      null;
+      ) : null;
 
     return (
       <div>
         { !this.state.loading &&
-          <div className="form-group">
-            <input type="search" className="form-control"
-              placeholder="Type to filter tables"
+          <div className='form-group'>
+            <input type='search' className='form-control'
+              placeholder='Type to filter tables'
               onChange={this._filter.bind(this)}/>
           </div>
         }
 
         {pagination}
 
-        <div ref="tableTree" style={{maxHeight: '350px', overflowY: 'auto'}}>
+        <div ref='tableTree' style={{maxHeight: '350px', overflowY: 'auto'}}>
           {tableTree}
         </div>
       </div>
@@ -187,14 +182,12 @@ class TableTree extends React.Component {
   }
 
   _onChange (page) {
-
     // so that page doesn't reset to beginning
     page = page || this.state.page || 1;
     this.setState(getState(page, filterString, this.props.database));
   }
 
   getDetails (tableName, database) {
-
     // find the table
     let table = this.state.tables.filter(table => {
       return tableName === table.name;
@@ -235,4 +228,8 @@ class TableTree extends React.Component {
 
 }
 
+TableTree.propTypes = {
+  database: React.PropTypes.string.isRequired
+};
+
 export default TableTree;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/constants/AdhocQueryConstants.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/constants/AdhocQueryConstants.js b/lens-ui/app/constants/AdhocQueryConstants.js
index 3c4f93a..ea8cbd0 100644
--- a/lens-ui/app/constants/AdhocQueryConstants.js
+++ b/lens-ui/app/constants/AdhocQueryConstants.js
@@ -17,7 +17,7 @@
 * under the License.
 */
 
-import KeyMirror from 'keyMirror';
+import KeyMirror from 'keymirror';
 
 const AdhocQueryConstants = KeyMirror({
   RECEIVE_CUBES: null,
@@ -45,7 +45,14 @@ const AdhocQueryConstants = KeyMirror({
   RECEIVE_QUERY_FAILED: null,
 
   RECEIVE_DATABASES: null,
-  RECEIVE_DATABASES_FAILED: null
+  RECEIVE_DATABASES_FAILED: null,
+
+  RECEIVE_QUERY_PARAMS_META: null,
+
+  SAVE_QUERY_SUCCESS: null,
+  SAVE_QUERY_FAILED: null,
+
+  RECEIVE_SAVED_QUERY: null
 });
 
 export default AdhocQueryConstants;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/constants/AppConstants.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/constants/AppConstants.js b/lens-ui/app/constants/AppConstants.js
index 48cd93e..075cffb 100644
--- a/lens-ui/app/constants/AppConstants.js
+++ b/lens-ui/app/constants/AppConstants.js
@@ -17,11 +17,12 @@
 * under the License.
 */
 
-import KeyMirror from 'keyMirror';
+import KeyMirror from 'keymirror';
 
 const AppConstants = KeyMirror({
   AUTHENTICATION_SUCCESS: null,
-  AUTHENTICATION_FAILED: null
+  AUTHENTICATION_FAILED: null,
+  RECEIVE_USERNAME: null
 });
 
 export default AppConstants;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/dispatcher/AppDispatcher.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/dispatcher/AppDispatcher.js b/lens-ui/app/dispatcher/AppDispatcher.js
index 31b267c..b87320c 100644
--- a/lens-ui/app/dispatcher/AppDispatcher.js
+++ b/lens-ui/app/dispatcher/AppDispatcher.js
@@ -5,7 +5,6 @@
  * This source code is licensed under the BSD-style license found in the
  * LICENSE file in the root directory of this source tree. An additional grant
  * of patent rights can be found in the PATENTS file in the same directory.
- *
  */
 
 import { Dispatcher } from 'flux';

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/AdhocQueryStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/AdhocQueryStore.js b/lens-ui/app/stores/AdhocQueryStore.js
index 7420270..3f880bf 100644
--- a/lens-ui/app/stores/AdhocQueryStore.js
+++ b/lens-ui/app/stores/AdhocQueryStore.js
@@ -33,7 +33,6 @@ var adhocDetails = {
   dbName: Config.dbName
 };
 
-// TODO remove this.
 function receiveQueryHandle (payload) {
   let id = payload.queryHandle.getElementsByTagName('handleId')[0].textContent;
   adhocDetails.queryHandle = id;
@@ -69,7 +68,6 @@ function receiveQueryResult (payload) {
     adhocDetails.queryResults[payload.handle].results = resultRows;
     adhocDetails.queryResults[payload.handle].columns = columns;
   } else {
-
     // persistent
     adhocDetails.queryResults[payload.handle] = {};
     adhocDetails.queryResults[payload.handle].downloadURL = payload.downloadURL;
@@ -87,19 +85,13 @@ let AdhocQueryStore = assign({}, EventEmitter.prototype, {
 
   // always returns the last-run-query's handle
   getQueryHandle () {
-    return adhocDetails.queryHandle;
-  },
-
-  clearQueryHandle () {
+    let handle = adhocDetails.queryHandle;
     adhocDetails.queryHandle = null;
+    return handle;
   },
 
-  getDbName () {
-    return adhocDetails.dbName
-  },
-
-  emitChange () {
-    this.emit(CHANGE_EVENT);
+  emitChange (hash) {
+    this.emit(CHANGE_EVENT, hash);
   },
 
   addChangeListener (callback) {
@@ -112,7 +104,7 @@ let AdhocQueryStore = assign({}, EventEmitter.prototype, {
 });
 
 AppDispatcher.register((action) => {
-  switch(action.actionType) {
+  switch (action.actionType) {
 
     case AdhocQueryConstants.RECEIVE_QUERY_HANDLE:
       receiveQueryHandle(action.payload);
@@ -132,6 +124,11 @@ AppDispatcher.register((action) => {
     case AdhocQueryConstants.RECEIVE_QUERY:
       receiveQuery(action.payload);
       AdhocQueryStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED:
+      AdhocQueryStore.emitChange(action.payload);
+      break;
   }
 });
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/CubeStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/CubeStore.js b/lens-ui/app/stores/CubeStore.js
index 8b20b95..09b469f 100644
--- a/lens-ui/app/stores/CubeStore.js
+++ b/lens-ui/app/stores/CubeStore.js
@@ -44,7 +44,6 @@ function receiveCubeDetails (payload) {
   cubes[cubeDetails.name].isLoaded = true;
 }
 
-
 let CHANGE_EVENT = 'change';
 var cubes = {};
 
@@ -67,7 +66,7 @@ let CubeStore = assign({}, EventEmitter.prototype, {
 });
 
 AppDispatcher.register((action) => {
-  switch(action.actionType) {
+  switch (action.actionType) {
     case AdhocQueryConstants.RECEIVE_CUBES:
       receiveCubes(action.payload);
       CubeStore.emitChange();

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/DatabaseStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/DatabaseStore.js b/lens-ui/app/stores/DatabaseStore.js
index 9f4490b..79894cf 100644
--- a/lens-ui/app/stores/DatabaseStore.js
+++ b/lens-ui/app/stores/DatabaseStore.js
@@ -26,7 +26,7 @@ function receiveDatabases (payload) {
   databases = [];
 
   databases = payload.databases.elements &&
-    payload.databases.elements.slice()
+    payload.databases.elements.slice();
 }
 
 let CHANGE_EVENT = 'change';
@@ -51,7 +51,7 @@ let DatabaseStore = assign({}, EventEmitter.prototype, {
 });
 
 AppDispatcher.register((action) => {
-  switch(action.actionType) {
+  switch (action.actionType) {
     case AdhocQueryConstants.RECEIVE_DATABASES:
       receiveDatabases(action.payload);
       DatabaseStore.emitChange();

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/SavedQueryStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/SavedQueryStore.js b/lens-ui/app/stores/SavedQueryStore.js
new file mode 100644
index 0000000..fb2869b
--- /dev/null
+++ b/lens-ui/app/stores/SavedQueryStore.js
@@ -0,0 +1,99 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+let savedQueries = {};
+let offset = 0;
+let totalRecords = 0;
+let CHANGE_EVENT = 'change';
+
+function receiveSavedQueries (payload) {
+  payload && payload.resoures.forEach(query => {
+    savedQueries[query.id] = query;
+  });
+
+  totalRecords = payload && payload.totalCount;
+}
+
+function receiveSavedQuery (payload) {
+  if (!savedQueries[payload.id]) totalRecords++;
+  savedQueries[payload.id] = payload;
+}
+
+let SavedQueryStore = assign({}, EventEmitter.prototype, {
+  getSavedQueries () {
+    return savedQueries;
+  },
+
+  getTotalRecords () {
+    return totalRecords;
+  },
+
+  getOffset () {
+    return offset;
+  },
+
+  emitChange (hash) {
+    this.emit(CHANGE_EVENT, hash);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+AppDispatcher.register((action) => {
+  switch (action.actionType) {
+    case AdhocQueryConstants.RECEIVE_SAVED_QUERIES:
+      receiveSavedQueries(action.payload);
+      SavedQueryStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_QUERY_PARAMS_META:
+      SavedQueryStore.emitChange({type: 'params', params: action.payload});
+      break;
+
+    case AdhocQueryConstants.SAVE_QUERY_SUCCESS:
+      SavedQueryStore.emitChange({
+        type: 'success',
+        message: action.payload,
+        id: action.payload && action.payload.id
+      });
+      break;
+
+    case AdhocQueryConstants.SAVE_QUERY_FAILED:
+      SavedQueryStore.emitChange({type: 'failure', message: action.payload});
+      break;
+
+    case AdhocQueryConstants.RECEIVE_SAVED_QUERY:
+      receiveSavedQuery(action.payload);
+      SavedQueryStore.emitChange();
+      break;
+  }
+});
+
+export default SavedQueryStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/TableStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/TableStore.js b/lens-ui/app/stores/TableStore.js
index 299d9e8..ee35b84 100644
--- a/lens-ui/app/stores/TableStore.js
+++ b/lens-ui/app/stores/TableStore.js
@@ -31,7 +31,7 @@ function receiveTables (payload) {
   }
 
   payload.tables.elements &&
-    payload.tables.elements.forEach( table => {
+    payload.tables.elements.forEach(table => {
       if (!tables[database][table]) {
         tables[database][table] = { name: table, isLoaded: false };
       }
@@ -86,7 +86,7 @@ let TableStore = assign({}, EventEmitter.prototype, {
 });
 
 AppDispatcher.register((action) => {
-  switch(action.actionType) {
+  switch (action.actionType) {
     case AdhocQueryConstants.RECEIVE_TABLES:
       receiveTables(action.payload);
       TableStore.emitChange();

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/stores/UserStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/UserStore.js b/lens-ui/app/stores/UserStore.js
index 47da021..ee5506f 100644
--- a/lens-ui/app/stores/UserStore.js
+++ b/lens-ui/app/stores/UserStore.js
@@ -17,8 +17,6 @@
 * under the License.
 */
 
-import React from 'react';
-
 import AppDispatcher from '../dispatcher/AppDispatcher';
 import AppConstants from '../constants/AppConstants';
 import assign from 'object-assign';
@@ -28,8 +26,7 @@ var CHANGE_EVENT = 'change';
 var userDetails = {
   isUserLoggedIn: false,
   email: '',
-  secretToken: '',
-  publicKey: ''
+  secretToken: ''
 };
 
 // keeping these methods out of the UserStore class as
@@ -38,13 +35,10 @@ function authenticateUser (details) {
   userDetails = {
     isUserLoggedIn: true,
     email: details.email,
-    secretToken: new XMLSerializer().serializeToString(details.secretToken),
-    publicKey: details.secretToken.getElementsByTagName('publicId')[0]
-      .textContent
+    secretToken: new XMLSerializer().serializeToString(details.secretToken)
   };
 
   // store the details in localStorage if available
-
   if (window.localStorage) {
     let adhocCred = assign({}, userDetails, { timestamp: Date.now() });
     window.localStorage.setItem('adhocCred', JSON.stringify(adhocCred));
@@ -52,7 +46,6 @@ function authenticateUser (details) {
 }
 
 function unauthenticateUser (details) {
-
   // details contains error code and message
   // which are not stored but passsed along
   // during emitChange()
@@ -69,12 +62,9 @@ function unauthenticateUser (details) {
 // exposing only necessary methods for the components.
 var UserStore = assign({}, EventEmitter.prototype, {
   isUserLoggedIn () {
-
     if (userDetails && userDetails.isUserLoggedIn) {
-
       return userDetails.isUserLoggedIn;
     } else if (window.localStorage && localStorage.getItem('adhocCred')) {
-
       // check in localstorage
       let credentials = JSON.parse(localStorage.getItem('adhocCred'));
 
@@ -114,7 +104,7 @@ var UserStore = assign({}, EventEmitter.prototype, {
 
 // registering callbacks with the dispatcher. So verbose?? I know right!
 AppDispatcher.register((action) => {
-  switch(action.actionType) {
+  switch (action.actionType) {
     case AppConstants.AUTHENTICATION_SUCCESS:
       authenticateUser(action.payload);
       UserStore.emitChange();

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/styles/css/global.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/global.css b/lens-ui/app/styles/css/global.css
index 131ab46..7670703 100644
--- a/lens-ui/app/styles/css/global.css
+++ b/lens-ui/app/styles/css/global.css
@@ -16,3 +16,25 @@
 * specific language governing permissions and limitations
 * under the License.
 */
+
+.no-padding {
+  padding: 0px;
+}
+
+.glyphicon.glyphicon-chevron-up, .glyphicon.glyphicon-chevron-down {
+  cursor: pointer;
+}
+
+.italics {
+  font-style: italic;
+}
+
+/*.panel-default > .blue-header {
+  background: rgba(51, 122, 183, 0.79);
+  color: white;
+}*/
+
+.panel-default > .blue-header:HOVER {
+  /*background: rgba(51, 122, 183, 1);*/
+  transform: scale(1.018);
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/styles/css/login.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/login.css b/lens-ui/app/styles/css/login.css
index b400cfb..194e19e 100644
--- a/lens-ui/app/styles/css/login.css
+++ b/lens-ui/app/styles/css/login.css
@@ -17,8 +17,7 @@
 * under the License.
 */
 
-
- /*For login form*/
+/*For login form*/
 .form-signin {
   max-width: 330px;
   padding: 15px;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/styles/css/query-component.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/query-component.css b/lens-ui/app/styles/css/query-component.css
index a82165e..e29758e 100644
--- a/lens-ui/app/styles/css/query-component.css
+++ b/lens-ui/app/styles/css/query-component.css
@@ -17,8 +17,7 @@
 * under the License.
 */
 
-
- @media (max-width: 768px) {
+@media (max-width: 768px) {
     .btn.responsive {
         width:100%;
         margin-bottom: 10px;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/styles/css/tree.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/tree.css b/lens-ui/app/styles/css/tree.css
index 402c9a0..61cc4e7 100644
--- a/lens-ui/app/styles/css/tree.css
+++ b/lens-ui/app/styles/css/tree.css
@@ -17,8 +17,7 @@
 * under the License.
 */
 
-
- .node {
+.node {
   font-weight: bold;
 }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/styles/less/globals.less
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/less/globals.less b/lens-ui/app/styles/less/globals.less
index c0704dc..05cc30e 100644
--- a/lens-ui/app/styles/less/globals.less
+++ b/lens-ui/app/styles/less/globals.less
@@ -17,7 +17,6 @@
 * under the License.
 */
 
-
- // IMPORTS
+// IMPORTS
 
 @import "~bootstrap/less/bootstrap.less";

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/app/utils/ErrorParser.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/utils/ErrorParser.js b/lens-ui/app/utils/ErrorParser.js
new file mode 100644
index 0000000..8bd0d90
--- /dev/null
+++ b/lens-ui/app/utils/ErrorParser.js
@@ -0,0 +1,53 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+let ErrorParser = {
+  getMessage (errorXML) {
+    let errors = [];
+
+    errors = Array.prototype.slice.call(errorXML.getElementsByTagName('error'))
+      .map(error => {
+        return {
+          code: error.getElementsByTagName('code')[0].textContent,
+          message: error.getElementsByTagName('message')[0].textContent
+        };
+      })
+      .sort((a, b) => {
+        return parseInt(a.code, 10) - parseInt(b.code, 10);
+      })
+      // removes duplicate error messages
+      .filter((item, pos, array) => {
+        return !pos || (item.code != (array[pos - 1] && array[pos - 1].code));
+      })
+      // removes not so helpful `Internal Server Error`
+      .filter(error => {
+        return error.code != 1001;
+      });
+
+    if (errors && errors.length == 0) {
+      errors[0] = {};
+      errors[0].code = 500;
+      errors[0].message = 'Oh snap! Something went wrong. Please try again later.';
+    }
+
+    return errors;
+  }
+};
+
+export default ErrorParser;

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/index.html
----------------------------------------------------------------------
diff --git a/lens-ui/index.html b/lens-ui/index.html
index 9c20fe9..62df140 100644
--- a/lens-ui/index.html
+++ b/lens-ui/index.html
@@ -80,6 +80,7 @@
         }
       }
     </style>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
   </head>
   <body>
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/package.json
----------------------------------------------------------------------
diff --git a/lens-ui/package.json b/lens-ui/package.json
index 920b120..b21302b 100644
--- a/lens-ui/package.json
+++ b/lens-ui/package.json
@@ -1,7 +1,6 @@
 {
   "name": "lens-ui",
-  "version": "1.0.0",
-  "description": "An exemplary front end solution for Apache LENS",
+  "description": "An exemplary front end solution for Apache LENS.",
   "main": "app/app.js",
   "scripts": {
     "start": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p && lensserver='http://0.0.0.0:9999/lensapi/' port=8082 node server.js",
@@ -13,39 +12,45 @@
     "bootstrap": "^3.3.4",
     "classnames": "^2.1.2",
     "codemirror": "^5.3.0",
+    "cookie-parser": "~1.3.5",
+    "debug": "~2.2.0",
+    "express": "~4.12.4",
+    "express-session": "latest",
     "flux": "^2.0.3",
     "halogen": "^0.1.8",
     "keymirror": "^0.1.1",
     "lodash": "^3.9.1",
     "moment": "^2.10.3",
+    "morgan": "~1.5.3",
     "object-assign": "^2.0.0",
     "q": "^1.4.1",
+    "qwest": "^2.0.7",
     "react": "^0.13.3",
-    "react-bootstrap": "^0.22.6",
+    "react-bootstrap": "0.25.1",
     "react-router": "^0.13.3",
     "react-treeview": "^0.3.12",
-    "reqwest": "^1.1.5"
+    "react-widgets": "^2.8.0",
+    "serve-favicon": "~2.2.1"
   },
   "devDependencies": {
     "autoprefixer-loader": "^1.2.0",
     "babel-core": "^5.4.3",
     "babel-loader": "^5.3.2",
     "babel-runtime": "^5.7.0",
-    "body-parser": "^1.13.2",
-    "cookie-parser": "^1.3.5",
     "css-loader": "^0.13.1",
     "express": "^4.12.4",
-    "express-session": "^1.11.3",
     "file-loader": "^0.8.1",
     "http-proxy": "^1.11.1",
     "json-loader": "^0.5.2",
     "less": "^2.5.0",
     "less-loader": "^2.2.0",
-    "morgan": "^1.6.1",
     "node-libs-browser": "^0.5.0",
-    "serve-favicon": "^2.3.0",
     "style-loader": "^0.12.2",
     "url-loader": "^0.5.5",
     "webpack": "^1.9.7"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://git-wip-us.apache.org/repos/asf/lens.git"
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/server.js
----------------------------------------------------------------------
diff --git a/lens-ui/server.js b/lens-ui/server.js
index e812018..736d862 100644
--- a/lens-ui/server.js
+++ b/lens-ui/server.js
@@ -19,41 +19,42 @@
 
 var express = require('express');
 var path = require('path');
-var favicon = require('serve-favicon');
 var logger = require('morgan');
 var cookieParser = require('cookie-parser');
-var bodyParser = require('body-parser');
 var session = require('express-session');
 
 var app = express();
 var httpProxy = require('http-proxy');
 var proxy = httpProxy.createProxyServer();
+
 var port = process.env['port'] || 8082;
 
 app.use(logger('dev'));
-app.use(bodyParser.json());
-app.use(bodyParser.urlencoded({ extended: false }));
 app.use(cookieParser());
 
 process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
 
-if(!process.env['lensserver']){
+if (!process.env['lensserver']) {
   throw new Error('Specify LENS Server address in `lensserver` argument');
 }
 
 console.log('Using this as your LENS Server Address: ', process.env['lensserver']);
 console.log('If this seems wrong, please edit `lensserver` argument in package.json. Do not forget to append http://\n');
 
-app.use( session({
-   secret            : 'SomethingYouKnow',
-   resave            : false,
-   saveUninitialized : true
+app.use(session({
+  secret            : 'SomethingYouKnow',
+  resave            : false,
+  saveUninitialized : true
 }));
 
-var fs = require('fs');
-
+var fs = require('fs')
+;
 app.use(express.static(path.resolve(__dirname, 'target', 'assets')));
 
+app.get('/health', function (req, res) {
+  res.status(200).send('Adhoc Query UI is up and running.');
+});
+
 app.get('/target/assets/*', function (req, res) {
   res.setHeader('Cache-Control', 'public');
   res.end(fs.readFileSync(__dirname + req.path));
@@ -62,18 +63,18 @@ app.get('/target/assets/*', function (req, res) {
 app.all('/serverproxy/*', function (req, res) {
   req.url = req.url.replace('serverproxy', '');
   proxy.web(req, res, {
-      target: process.env['lensserver']
-  }, function (e) { console.log('Handled error.'); });
+    target: process.env['lensserver']
+  }, function (e) {
+    console.error('Proxy Error: ', e);
+  });
 });
 
-app.get('*', function(req, res) {
+app.get('*', function (req, res) {
   res.end(fs.readFileSync(__dirname + '/index.html'));
 });
 
-var server = app.listen(port, function(err) {
-  if(err) throw err;
-
-  var port = server.address().port;
+var server = app.listen(port, function (err) {
+  if (err) throw err;
 
-  console.log('Ad hoc UI server listening at port: ', port);
+  console.log('Ad hoc UI server listening at %s', port);
 });

http://git-wip-us.apache.org/repos/asf/lens/blob/86714211/lens-ui/webpack.config.js
----------------------------------------------------------------------
diff --git a/lens-ui/webpack.config.js b/lens-ui/webpack.config.js
index ab4021f..9977049 100644
--- a/lens-ui/webpack.config.js
+++ b/lens-ui/webpack.config.js
@@ -20,7 +20,6 @@
 var webpack = require('webpack');
 var path = require('path');
 
-
 module.exports = {
 
   entry: {
@@ -29,27 +28,30 @@ module.exports = {
     ]
   },
 
-	output: {
+  output: {
     path: path.join(__dirname, 'target', 'assets'),
-		filename: 'bundle.js'
-	},
+    filename: 'bundle.js'
+  },
 
   plugins: [
     new webpack.NoErrorsPlugin()
   ],
 
+  devtool: 'source-map',
+
   resolve: {
     modulesDirectories: ['app', 'node_modules', __dirname]
   },
 
-	module: {
-		loaders: [
+  module: {
+    loaders: [
       { test: /\.jsx?$/, loaders: ['babel'], include: path.join(__dirname, 'app') },
-			{ test: /\.css$/, loaders: ['style', 'css'] },
+      { test: /\.css$/, loaders: ['style', 'css'] },
       { test: /\.less$/, loaders: ['style', 'css', 'autoprefixer', 'less'] },
       { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loaders: ['url?limit=10000&minetype=application/font-woff'] },
       { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loaders: ['file'] },
-      { test: /\.json$/, loaders: ['json']}
-		]
-	}
+      { test: /\.json$/, loaders: ['json'] },
+      { test: /\.gif$/, loader: 'url-loader?mimetype=image/png' }
+    ]
+  }
 };


[26/50] [abbrv] lens git commit: LENS-399 : Fix powermock test failure on jdk8

Posted by ra...@apache.org.
LENS-399 : Fix powermock test failure on jdk8


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/5f60bdc6
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/5f60bdc6
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/5f60bdc6

Branch: refs/heads/current-release-line
Commit: 5f60bdc62f8e5db288fa8967fa0f865a044386d1
Parents: f4c6c11
Author: Raju Bairishetti <ra...@apache.org>
Authored: Mon Sep 21 11:23:33 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Mon Sep 21 11:23:33 2015 +0530

----------------------------------------------------------------------
 .../test/java/org/apache/lens/server/rewrite/TestRewriting.java    | 2 +-
 pom.xml                                                            | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/5f60bdc6/lens-server/src/test/java/org/apache/lens/server/rewrite/TestRewriting.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/rewrite/TestRewriting.java b/lens-server/src/test/java/org/apache/lens/server/rewrite/TestRewriting.java
index 7be9793..2827b96 100644
--- a/lens-server/src/test/java/org/apache/lens/server/rewrite/TestRewriting.java
+++ b/lens-server/src/test/java/org/apache/lens/server/rewrite/TestRewriting.java
@@ -57,7 +57,7 @@ import com.codahale.metrics.MetricRegistry;
  */
 @PrepareForTest(RewriteUtil.class)
 @PowerMockIgnore({"org.apache.log4j.*", "javax.management.*", "javax.xml.*",
-  "com.sun.org.apache.xerces.internal.jaxp.*", "ch.qos.logback.*", "org.slf4j.*", "org.w3c.dom*"})
+  "com.sun.org.apache.xerces.internal.jaxp.*", "ch.qos.logback.*", "org.slf4j.*", "org.w3c.dom*", "org.mockito.*"})
 public class TestRewriting {
   /**
    * We need a special {@link IObjectFactory}.

http://git-wip-us.apache.org/repos/asf/lens/blob/5f60bdc6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index adba544..10f9bc1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,7 +87,7 @@
     <!-- test -->
     <testng.version>6.8</testng.version>
     <mockito.version>1.9.5</mockito.version>
-    <powermock.version>1.4.12</powermock.version>
+    <powermock.version>1.5.6</powermock.version>
 
     <!-- maven plugins -->
     <jaxb2.plugin.version>0.12.3</jaxb2.plugin.version>


[09/50] [abbrv] lens git commit: LENS-758 : Remove feather logo from the repository, use already existing image to display on website.

Posted by ra...@apache.org.
LENS-758 : Remove feather logo from the repository, use already existing image to display on website.


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

Branch: refs/heads/current-release-line
Commit: ea8bc91153655e047e989054f1fe65cca3ebb973
Parents: 6efecda
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Mon Aug 31 22:15:58 2015 +0530
Committer: Raghavendra Singh <ra...@apache.org>
Committed: Mon Aug 31 22:15:58 2015 +0530

----------------------------------------------------------------------
 src/site/resources/images/apache-feather-tm.gif | Bin 6735 -> 0 bytes
 src/site/site.xml                               |   2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/ea8bc911/src/site/resources/images/apache-feather-tm.gif
----------------------------------------------------------------------
diff --git a/src/site/resources/images/apache-feather-tm.gif b/src/site/resources/images/apache-feather-tm.gif
deleted file mode 100644
index 3e8abc1..0000000
Binary files a/src/site/resources/images/apache-feather-tm.gif and /dev/null differ

http://git-wip-us.apache.org/repos/asf/lens/blob/ea8bc911/src/site/site.xml
----------------------------------------------------------------------
diff --git a/src/site/site.xml b/src/site/site.xml
index 4f4667c..ad862f3 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -34,7 +34,7 @@
 
   <bannerRight>
       <name>Apache</name>
-      <src>/images/apache-feather-tm.gif</src>
+      <src>http://www.apache.org/images/feather-small.gif</src>
       <href>http://www.apache.org</href>
   </bannerRight>
 


[10/50] [abbrv] lens git commit: LENS-737 : Throw single error out with LensMultiException

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
index 603d7cb..ac1c558 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
@@ -31,7 +31,9 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.error.LensError;
 import org.apache.lens.api.result.LensAPIResult;
 import org.apache.lens.api.result.LensErrorTO;
+import org.apache.lens.server.api.LensErrorInfo;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 
 import lombok.Getter;
@@ -41,14 +43,28 @@ import lombok.NonNull;
  * The Class LensException.
  */
 @SuppressWarnings("serial")
-public class LensException extends Exception {
+public class LensException extends Exception implements Comparable<LensException> {
 
   private static final int DEFAULT_LENS_EXCEPTION_ERROR_CODE = INTERNAL_SERVER_ERROR.getValue();
+  private static final int DEFAULT_LENS_EXCEPTION_WEIGHT = 0;
+
+  private static  LensErrorInfo defaultErrorInfo =
+      new LensErrorInfo(DEFAULT_LENS_EXCEPTION_ERROR_CODE, DEFAULT_LENS_EXCEPTION_WEIGHT, INTERNAL_SERVER_ERROR.name());
 
-  @Getter
-  private final int errorCode;
   private Object[] errorMsgFormattingArgs = new Object[0];
 
+  @Getter
+  private final LensErrorInfo errorInfo;
+
+  public int getErrorCode() {
+    return errorInfo.getErrorCode();
+  }
+
+  public int getErrorWeight() {
+    return errorInfo.getErrorWeight();
+  }
+
+
   /**
    * The lensResponse prepared by {@link #buildLensErrorResponse(ErrorCollection, String, String)}
    * */
@@ -61,7 +77,7 @@ public class LensException extends Exception {
    * @see Exception#Exception(String)
    */
   public LensException(String errorMsg) {
-    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
+    this(errorMsg, defaultErrorInfo);
   }
 
   /**
@@ -70,7 +86,7 @@ public class LensException extends Exception {
    * @see Exception#Exception(String, Throwable)
    */
   public LensException(String errorMsg, Throwable cause) {
-    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
+    this(errorMsg, defaultErrorInfo, cause);
   }
 
   /**
@@ -79,7 +95,7 @@ public class LensException extends Exception {
    * @see Exception#Exception()
    */
   public LensException() {
-    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
+    this(null, defaultErrorInfo);
   }
 
   /**
@@ -88,79 +104,100 @@ public class LensException extends Exception {
    * @see Exception#Exception(Throwable)
    */
   public LensException(Throwable cause) {
-    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
+    this(defaultErrorInfo, cause);
   }
 
   /**
-   * Constructs a new Lens Exception with error code.
+   * Constructs a new Lens Exception with error info.
    *
    * @see Exception#Exception()
    */
-  public LensException(final int errorCode) {
-    this(null, errorCode);
+  public LensException(final LensErrorInfo errorInfo) {
+    this(null, errorInfo);
   }
 
   /**
-   * Constructs a new Lens Exception with error msg and error code.
+   * Constructs a new Lens Exception with error msg and error info.
    *
    * @see Exception#Exception()
    */
-  public LensException(final String errorMsg, final int errorCode) {
-    this(errorMsg, errorCode, null);
+  public LensException(final String errorMsg, final LensErrorInfo errorInfo) {
+    this(errorMsg, errorInfo, null);
   }
 
   /**
-   * Constructs a new Lens Exception with error code, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with error info, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final int errorCode, final Throwable cause, @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorCode, cause, errorMsgFormattingArgs);
+  public LensException(final LensErrorInfo errorInfo, final Throwable cause,
+      @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorInfo, cause, errorMsgFormattingArgs);
   }
 
   /**
-   * Constructs a new Lens Exception with error code and error msg formatting arguments.
+   * Constructs a new Lens Exception with error info and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final int errorCode, @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorCode, null, errorMsgFormattingArgs);
+  public LensException(final LensErrorInfo errorInfo, @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorInfo, null, errorMsgFormattingArgs);
   }
 
-
   /**
-   * Constructs a new Lens Exception with exception error message, error code, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with exception error message, error info, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final String errorMsg, final int errorcode, final Throwable cause,
+  public LensException(final String errorMsg, final LensErrorInfo errorInfo, final Throwable cause,
     @NonNull final Object... errorMsgFormattingArgs) {
 
-    super(errorMsg, cause);
-    checkArgument(errorcode > 0);
+    super(getErrorMessage(errorMsg, errorInfo, errorMsgFormattingArgs), cause);
+    checkArgument(errorInfo.getErrorCode() > 0);
 
-    this.errorCode = errorcode;
+    this.errorInfo =  errorInfo;
     this.errorMsgFormattingArgs = errorMsgFormattingArgs;
   }
 
+  private static String getErrorMessage(final String errorMsg, final LensErrorInfo errorInfo,
+      @NonNull final Object... errorMsgFormattingArgs) {
+
+    if (StringUtils.isBlank(errorMsg)) {
+      StringBuilder error = new StringBuilder(errorInfo.getErrorName());
+      if (errorMsgFormattingArgs != null && errorMsgFormattingArgs.length != 0) {
+        error.append(Arrays.asList(errorMsgFormattingArgs));
+      }
+      return error.toString();
+    }
+    return errorMsg;
+  }
+
+  /**
+   * Copy Constructor
+   * @param e
+   */
+  public LensException(LensException e) {
+    this(e.getMessage(), e.getErrorInfo(), e.getCause(), e.errorMsgFormattingArgs);
+  }
+
   public final void buildLensErrorResponse(final ErrorCollection errorCollection,
     final String apiVersion, final String id) {
 
-    final LensError lensError = errorCollection.getLensError(errorCode);
+    final LensError lensError = errorCollection.getLensError(getErrorCode());
     final LensErrorTO lensErrorTO = buildLensErrorTO(errorCollection, lensError);
     lensAPIResult = LensAPIResult.composedOf(apiVersion, id, lensErrorTO, lensError.getHttpStatusCode());
   }
 
   public final LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection) {
 
-    final LensError lensError = errorCollection.getLensError(errorCode);
+    final LensError lensError = errorCollection.getLensError(getErrorCode());
     return buildLensErrorTO(errorCollection, lensError);
   }
 
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
     final String stackTrace) {
 
-    return LensErrorTO.composedOf(errorCode, errorMsg, stackTrace);
+    return LensErrorTO.composedOf(getErrorCode(), errorMsg, stackTrace);
   }
 
   private LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final LensError lensError) {
@@ -182,7 +219,7 @@ public class LensException extends Exception {
     }
 
     LensException e = (LensException) o;
-    if (errorCode == e.errorCode && isErrorMsgEqual(e)
+    if (errorInfo.equals(e.errorInfo) && isErrorMsgEqual(e)
       && Arrays.deepEquals(errorMsgFormattingArgs, e.errorMsgFormattingArgs)) {
       return true;
     }
@@ -216,7 +253,7 @@ public class LensException extends Exception {
     final int PRIME = 59;
     int result = 1;
 
-    result = result * PRIME + errorCode;
+    result = result * PRIME + errorInfo.hashCode();
     result = result * PRIME + (this.getMessage() == null ? 0 : this.getMessage().hashCode());
     result = result * PRIME + Arrays.deepHashCode(errorMsgFormattingArgs);
     return result;
@@ -228,4 +265,9 @@ public class LensException extends Exception {
     }
     return new LensException(e);
   }
+
+  @Override
+  public int compareTo(LensException e) {
+    return this.getErrorWeight() - e.getErrorWeight();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
index af9e33a..5248489 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
@@ -18,10 +18,7 @@
  */
 package org.apache.lens.server.api.error;
 
-import static org.apache.lens.api.error.LensCommonErrorCode.INTERNAL_SERVER_ERROR;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -29,6 +26,7 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.result.LensErrorTO;
 
 import com.google.common.collect.ImmutableList;
+
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NonNull;
@@ -50,14 +48,14 @@ public class LensMultiCauseException extends LensException {
   @Getter(AccessLevel.PROTECTED)
   private final ImmutableList<LensException> causes;
 
-  public LensMultiCauseException(final String errMsg, @NonNull
-    final ImmutableList<LensException> causes) {
-
-    super(errMsg, INTERNAL_SERVER_ERROR.getValue());
-    checkArgument(causes.size() >= 2, "LensMultiCauseException should only be created when there are atleast "
-        + "two causes. An instance of LensException should be sufficient if there is only one cause.");
+  public LensMultiCauseException(@NonNull final ImmutableList<LensException> excpList) {
+    super(getAppropriateError(excpList));
+    this.causes = excpList;
+  }
 
-    this.causes = causes;
+  // Get appropriate error code
+  public static LensException getAppropriateError(final ImmutableList<LensException> excpList) {
+    return Collections.max(excpList);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
index 917eba3..dc20f0f 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
@@ -18,20 +18,22 @@
  */
 package org.apache.lens.server.error;
 
+import org.apache.lens.server.api.LensErrorInfo;
+
 public enum LensServerErrorCode {
 
-  SESSION_ID_NOT_PROVIDED(2001),
-  NULL_OR_EMPTY_OR_BLANK_QUERY(2002),
-  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003);
+  SESSION_ID_NOT_PROVIDED(2001, 0),
+  NULL_OR_EMPTY_OR_BLANK_QUERY(2002, 0),
+  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003, 0);
 
-  public int getValue() {
-    return this.errorCode;
+  public LensErrorInfo getLensErrorInfo() {
+    return this.errorInfo;
   }
 
-  private LensServerErrorCode(final int code) {
-    this.errorCode = code;
+  LensServerErrorCode(final int code, final int weight) {
+    this.errorInfo = new LensErrorInfo(code, weight, name());
   }
 
-  private final int errorCode;
+  private final LensErrorInfo errorInfo;
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
index 366b306..d90f8fd 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
@@ -31,11 +31,11 @@ public class UnSupportedQuerySubmitOpException extends LensException {
   private final SupportedQuerySubmitOperations supportedOps = new SupportedQuerySubmitOperations();
 
   public UnSupportedQuerySubmitOpException() {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue());
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo());
   }
 
   public UnSupportedQuerySubmitOpException(final Throwable cause) {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(), cause);
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo(), cause);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index c29a1ac..23cc748 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -1275,7 +1275,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           final LensException firstCause = causes.get(0);
           for (LensException cause : causes) {
             if (!cause.equals(firstCause)) {
-              throw new LensMultiCauseException(StringUtils.join(failureCauses, '\n'), ImmutableList.copyOf(causes));
+              throw new LensMultiCauseException(ImmutableList.copyOf(causes));
             }
           }
           throw firstCause;
@@ -1555,15 +1555,11 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       if (prepared != null) {
         destroyPreparedQuery(prepared);
       }
-      log.error("Explain and prepare failed", e);
-      QueryPlan plan;
-      if (e.getCause() != null && e.getCause().getMessage() != null) {
-        plan = new QueryPlan(true, e.getCause().getMessage());
-      } else {
-        plan = new QueryPlan(true, e.getMessage());
-      }
-      return plan;
+      throw e;
     } catch (UnsupportedEncodingException e) {
+      if (prepared != null) {
+        destroyPreparedQuery(prepared);
+      }
       throw new LensException(e);
     } finally {
       release(sessionHandle);
@@ -2259,25 +2255,16 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public QueryPlan explain(final String requestId, LensSessionHandle sessionHandle, String query, LensConf lensConf)
     throws LensException {
     try {
-      log.info("Explain: session:{} query:{}",  sessionHandle, query);
+      log.info("Explain: session:{} query:{}", sessionHandle, query);
       acquire(sessionHandle);
       Configuration qconf = getLensConf(sessionHandle, lensConf);
-      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query,
-        getSession(sessionHandle).getLoggedInUser(), lensConf, qconf, drivers.values());
+      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query, getSession(sessionHandle)
+          .getLoggedInUser(), lensConf, qconf, drivers.values());
       explainQueryContext.setLensSessionIdentifier(sessionHandle.getPublicId().toString());
       accept(query, qconf, SubmitOp.EXPLAIN);
       rewriteAndSelect(explainQueryContext);
       addSessionResourcesToDriver(explainQueryContext);
       return explainQueryContext.getSelectedDriver().explain(explainQueryContext).toQueryPlan();
-    } catch (LensException e) {
-      log.error("Error during explain :", e);
-      QueryPlan plan;
-      if (e.getCause() != null && e.getCause().getMessage() != null) {
-        plan = new QueryPlan(true, e.getCause().getMessage());
-      } else {
-        plan = new QueryPlan(true, e.getMessage());
-      }
-      return plan;
     } catch (UnsupportedEncodingException e) {
       throw new LensException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
index 6bfd77a..96f6aea 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
@@ -77,7 +77,7 @@ public class QueryServiceResource {
 
   private void validateSessionId(final LensSessionHandle sessionHandle) throws LensException {
     if (sessionHandle == null) {
-      throw new LensException(SESSION_ID_NOT_PROVIDED.getValue());
+      throw new LensException(SESSION_ID_NOT_PROVIDED.getLensErrorInfo());
     }
   }
 
@@ -104,7 +104,7 @@ public class QueryServiceResource {
 
   private void validateQuery(String query) throws LensException {
     if (StringUtils.isBlank(query)) {
-      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue());
+      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo());
     }
   }
   /**
@@ -340,19 +340,24 @@ public class QueryServiceResource {
    * @return {@link QueryPrepareHandle} incase of {link org.apache.lens.api.query.SubmitOp#PREPARE} operation.
    *         {@link QueryPlan} incase of {@link org.apache.lens.api.query.SubmitOp#EXPLAIN_AND_PREPARE}
    *         and the query plan will contain the prepare handle as well.
+   * @throws LensException
    */
   @POST
   @Path("preparedqueries")
   @Consumes({MediaType.MULTIPART_FORM_DATA})
   @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
   @MultiPurposeResource(formParamName = "operation")
-  public QuerySubmitResult prepareQuery(@FormDataParam("sessionid") LensSessionHandle sessionid,
-    @FormDataParam("query") String query, @DefaultValue("") @FormDataParam("operation") String operation,
-    @FormDataParam("conf") LensConf conf, @DefaultValue("") @FormDataParam("queryName") String queryName) {
+  public LensAPIResult<? extends QuerySubmitResult> prepareQuery(
+      @FormDataParam("sessionid") LensSessionHandle sessionid, @FormDataParam("query") String query,
+      @DefaultValue("") @FormDataParam("operation") String operation, @FormDataParam("conf") LensConf conf,
+      @DefaultValue("") @FormDataParam("queryName") String queryName) throws LensException {
+    final String requestId = this.logSegregationContext.getLogSegragationId();
+
     try {
       checkSessionId(sessionid);
       checkQuery(query);
       SubmitOp sop = null;
+      QuerySubmitResult result;
       try {
         sop = SubmitOp.valueOf(operation.toUpperCase());
       } catch (IllegalArgumentException e) {
@@ -363,17 +368,20 @@ public class QueryServiceResource {
       }
       switch (sop) {
       case PREPARE:
-        return queryServer.prepare(sessionid, query, conf, queryName);
+        result = queryServer.prepare(sessionid, query, conf, queryName);
+        break;
       case EXPLAIN_AND_PREPARE:
-        return queryServer.explainAndPrepare(sessionid, query, conf, queryName);
+        result = queryServer.explainAndPrepare(sessionid, query, conf, queryName);
+        break;
       default:
         throw new BadRequestException("Invalid operation type: " + operation + prepareClue);
       }
+      return LensAPIResult.composedOf(null, requestId, result);
     } catch (LensException e) {
-      throw new WebApplicationException(e);
+      e.buildLensErrorResponse(errorCollection, null, requestId);
+      throw e;
     }
   }
-
   /**
    * Destroy all the prepared queries; Can be filtered with user.
    *
@@ -390,10 +398,11 @@ public class QueryServiceResource {
    */
   @DELETE
   @Path("preparedqueries")
-  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
+  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
   public APIResult destroyPreparedQueries(@QueryParam("sessionid") LensSessionHandle sessionid,
-    @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
-    @DefaultValue("-1") @QueryParam("fromDate") long fromDate, @DefaultValue("-1") @QueryParam("toDate") long toDate) {
+      @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
+      @DefaultValue("-1") @QueryParam("fromDate") long fromDate,
+      @DefaultValue("-1") @QueryParam("toDate") long toDate) {
     checkSessionId(sessionid);
     int numDestroyed = 0;
     boolean failed = false;

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
index 38b5ea0..4d4f137 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
@@ -49,7 +49,7 @@ public class ErrorResponseExpectedData {
 
     /* Assert Equal LensErrorTO (stack trace gets excluded in equality check) */
     final LensErrorTO actualLensErrorTO = lensAPIResult.getLensErrorTO();
-    assertEquals(actualLensErrorTO, expectedLensErrorTO);
+    assertEquals(actualLensErrorTO.getMessage(), expectedLensErrorTO.getMessage());
 
     /* Assert receipt of valid stacktraces */
     assertTrue(lensAPIResult.areValidStackTracesPresent(), "Received Lens Response:" + lensAPIResult);

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
index 64a75ce..2f74ceb 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
@@ -34,7 +34,7 @@ public class FailingQueryDriver extends MockDriver {
     if (ctx.getUserQuery().contains("fail")) {
       return new FactPartitionBasedQueryCost(0.0);
     } else {
-      throw new LensException();
+      throw new LensException("Simulated Estimate Failure");
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
index 2189eb8..18a8c8d 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
@@ -111,8 +111,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.<LensSessionHandle>absent(), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Session id not provided. Please provide a session id.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SESSION_ID_NOT_PROVIDED.getValue(), expectedErrMsg,
-      MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        SESSION_ID_NOT_PROVIDED.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -126,8 +126,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), testQuery);
 
     final String expectedErrMsg = "Query is not provided, or it is empty or blank. Please provide a valid query.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue(), expectedErrMsg,
-      MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -144,7 +144,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     final String expectedErrMsg = "Provided Operation is not supported. Supported Operations are: "
       + "[estimate, execute, explain, execute_with_timeout]";
 
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo().getErrorCode(),
       expectedErrMsg, MOCK_STACK_TRACE, new SupportedQuerySubmitOperations());
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -165,11 +166,9 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       expectedErrMsg, MOCK_STACK_TRACE);
     LensErrorTO childError2 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
         expectedErrMsg, MOCK_STACK_TRACE);
-    LensErrorTO childError3 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE);
 
     LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2, childError3));
+        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2));
 
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(Status.INTERNAL_SERVER_ERROR,
       expectedLensErrorTO);
@@ -185,7 +184,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Syntax Error: line 1:0 cannot recognize input near 'mock' '-' 'query'";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getValue(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getLensErrorInfo().getErrorCode(),
       expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -290,8 +289,9 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       final ColUnAvailableInTimeRange expectedErrorPayload = new ColUnAvailableInTimeRange(testDimensionField,
         expecAvailableFrom, expecAvailableTill);
 
-      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
+      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+          COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
+          expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
       ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
       expectedData.verify(response);

http://git-wip-us.apache.org/repos/asf/lens/blob/309a7ed5/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index b3f5d93..fa8d6ee 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -375,7 +375,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
+        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
     assertEquals(plan2.getTablesQueried().size(), 1);
     assertTrue(plan2.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan2.getPrepareHandle());
@@ -387,47 +387,41 @@ public class TestQueryService extends LensJerseyTest {
    * Test explain failure.
    *
    * @throws InterruptedException the interrupted exception
+   * @throws UnsupportedEncodingException
    */
   @Test
-  public void testExplainFailure() throws InterruptedException {
+  public void testExplainFailure() throws InterruptedException, UnsupportedEncodingException {
     final WebTarget target = target().path("queryapi/queries");
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(),
-      "select NO_ID from " + TEST_TABLE));
+        MediaType.APPLICATION_XML_TYPE));
+    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
+        + TEST_TABLE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
 
-    final QueryPlan plan = target.request()
-      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
-    assertTrue(plan.isError());
-    assertNotNull(plan.getErrorMsg());
-    assertTrue(plan.getErrorMsg()
-      .contains("Invalid table alias or column reference 'NO_ID': " + "(possible column names are: id, idstr)"));
+    final Response responseExplain = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    assertEquals(responseExplain.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
 
     // Test explain and prepare
     final WebTarget ptarget = target().path("queryapi/preparedqueries");
 
     final FormDataMultiPart mp2 = new FormDataMultiPart();
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-      + TEST_TABLE));
+        + TEST_TABLE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain_and_prepare"));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
 
-    final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
-    assertTrue(plan2.isError());
-    assertNotNull(plan2.getErrorMsg());
-    assertNull(plan2.getPrepareHandle());
-    assertTrue(plan2.getErrorMsg().contains("Invalid table alias or column reference 'NO_ID': "
-      + "(possible column names are: id, idstr)"));
+    final Response responseExplainAndPrepare = target.request().post(
+        Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    assertEquals(responseExplainAndPrepare.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
   }
 
   // post to preparedqueries
@@ -457,7 +451,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPrepareHandle pHandle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPrepareHandle.class);
+        new GenericType<LensAPIResult<QueryPrepareHandle>>() {}).getData();
 
     // Get all prepared queries
     List<QueryPrepareHandle> allQueries = (List<QueryPrepareHandle>) target.queryParam("sessionid", lensSessionId)
@@ -555,7 +549,9 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan = target.request()
-      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), QueryPlan.class);
+      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
+          new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+
     assertEquals(plan.getTablesQueried().size(), 1);
     assertTrue(plan.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan.getPrepareHandle());
@@ -1425,7 +1421,9 @@ public class TestQueryService extends LensJerseyTest {
     final Response response = target.request()
       .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
 
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue(),
+
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo().getErrorCode(),
       "Neither cube nor dimensions accessed in the query", TestDataUtils.MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 


[39/50] [abbrv] lens git commit: LENS-113 : (Incremental) Document how to add feature documentation

Posted by ra...@apache.org.
LENS-113 : (Incremental) Document how to add feature documentation


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

Branch: refs/heads/current-release-line
Commit: e1848810591dd9c31e0993dbed977bcf0c627643
Parents: e5b793c
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Thu Oct 1 15:58:37 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Thu Oct 1 15:58:37 2015 +0530

----------------------------------------------------------------------
 src/site/apt/developer/contribute.apt | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/e1848810/src/site/apt/developer/contribute.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/developer/contribute.apt b/src/site/apt/developer/contribute.apt
index 6183b07..5b6fbaf 100644
--- a/src/site/apt/developer/contribute.apt
+++ b/src/site/apt/developer/contribute.apt
@@ -509,8 +509,14 @@ Developer Documentation : How to contribute to Apache Lens?
 
   * Who are the users of feature and who are not, if any.
 
+  * Illustration with example would be very welcome
+
   The design documentation related to the feature can go in developer documentation or
-  {{{https://cwiki.apache.org/confluence/display/LENS/DesignDocs} Design docs}}.
+  {{{https://cwiki.apache.org/confluence/display/LENS/DesignDocs} Design docs}}. It would be necessary to add in which
+  version the feature is available if the documentation is in confluence. Also when behavior is modified or improved on
+  existing features, version tagging is quite useful. Any defaults (in terms of config or behavior) assumed with the
+  feature should also be highlighted. Configuration descriptions should be linked to config apt files, so that they
+  are always in sync with code.
 
 ** Confluence usage
 


[40/50] [abbrv] lens git commit: LENS-790: UI Module failing if maven version is < 3.1

Posted by ra...@apache.org.
LENS-790: UI Module failing if maven version is < 3.1


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

Branch: refs/heads/current-release-line
Commit: ebb2c036634b8257ffa007ddeb6c1e2178fc0ae2
Parents: e184881
Author: Ankeet Maini <an...@gmail.com>
Authored: Mon Oct 5 13:36:28 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Mon Oct 5 13:36:28 2015 +0530

----------------------------------------------------------------------
 lens-ui/pom.xml | 36 ++++--------------------------------
 pom.xml         | 21 ++++++++++++++++++---
 2 files changed, 22 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/ebb2c036/lens-ui/pom.xml
----------------------------------------------------------------------
diff --git a/lens-ui/pom.xml b/lens-ui/pom.xml
index 69bcee5..b1ad565 100644
--- a/lens-ui/pom.xml
+++ b/lens-ui/pom.xml
@@ -35,42 +35,14 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <version>${antrun.plugin.version}</version>
-        <configuration>
-          <target>
-            <zip destfile="target/${project.artifactId}-${project.version}" basedir="${project.basedir}" excludes="target/**" />
-          </target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>com.github.eirslett</groupId>
-        <artifactId>frontend-maven-plugin</artifactId>
-        <version>${frontend.maven.plugin}</version>
+        <groupId>io.wcm.maven.plugins</groupId>
+        <artifactId>nodejs-maven-plugin</artifactId>
         <executions>
           <execution>
-            <id>install node and npm</id>
-            <goals>
-              <goal>install-node-and-npm</goal>
-            </goals>
-            <configuration>
-              <nodeVersion>${nodeVersion}</nodeVersion>
-              <npmVersion>${npmVersion}</npmVersion>
-              <nodeDownloadRoot>https://nodejs.org/dist/</nodeDownloadRoot>
-              <npmDownloadRoot>http://registry.npmjs.org/npm/-/</npmDownloadRoot>
-              <installDirectory>node</installDirectory>
-            </configuration>
-          </execution>
-          <execution>
-            <id>npm install</id>
+            <phase>compile</phase>
             <goals>
-              <goal>npm</goal>
+              <goal>run</goal>
             </goals>
-            <!-- Optional configuration which provides for running any npm command -->
-            <configuration>
-              <arguments>install</arguments>
-            </configuration>
           </execution>
         </executions>
       </plugin>

http://git-wip-us.apache.org/repos/asf/lens/blob/ebb2c036/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index dd26713..3ec5e5e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,9 +108,9 @@
     <cobertura.plugin.version>2.7</cobertura.plugin.version>
 
     <!-- UI -->
-    <frontend.maven.plugin>0.0.23</frontend.maven.plugin>
-    <nodeVersion>v4.0.0</nodeVersion>
-    <npmVersion>2.7.6</npmVersion>
+    <nodejs.plugin.version>1.0.0</nodejs.plugin.version>
+    <nodeVersion>0.10.32</nodeVersion>
+    <npmVersion>1.4.9</npmVersion>
 
     <!-- debian -->
     <mvn.deb.build.dir>${project.build.directory}/debian</mvn.deb.build.dir>
@@ -525,6 +525,21 @@
           <artifactId>findbugs-maven-plugin</artifactId>
           <version>${findbugs.plugin.version}</version>
         </plugin>
+        <plugin>
+          <groupId>io.wcm.maven.plugins</groupId>
+          <artifactId>nodejs-maven-plugin</artifactId>
+          <version>${nodejs.plugin.version}</version>
+          <configuration>
+            <npmVersion>${npmVersion}</npmVersion>
+            <nodeJsVersion>${nodeVersion}</nodeJsVersion>
+            <nodeJsDirectory>${project.basedir}/node</nodeJsDirectory>
+            <tasks>
+              <npmInstallTask>
+                <workingDirectory>${project.basedir}</workingDirectory>
+              </npmInstallTask>
+            </tasks>
+          </configuration>
+        </plugin>
       </plugins>
     </pluginManagement>
     <plugins>


[30/50] [abbrv] lens git commit: LENS-693 : Queries get purged as soon as they are finished

Posted by ra...@apache.org.
LENS-693 : Queries get purged as soon as they are finished


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/669e8727
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/669e8727
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/669e8727

Branch: refs/heads/current-release-line
Commit: 669e8727292a297487dbeb2b3edc6f17c2cea651
Parents: d457dd0
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Wed Sep 23 14:36:40 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Wed Sep 23 14:36:40 2015 +0530

----------------------------------------------------------------------
 .../main/java/org/apache/lens/api/LensConf.java |   7 +-
 .../lens/api/query/InMemoryQueryResult.java     |  24 +-
 .../org/apache/lens/api/query/LensQuery.java    |   8 +-
 .../lens/api/query/PersistentQueryResult.java   |  18 +
 .../org/apache/lens/api/query/QueryResult.java  |   4 +-
 .../org/apache/lens/api/query/QueryStatus.java  |   1 +
 .../lens/cli/commands/LensQueryCommands.java    |   9 +-
 .../org/apache/lens/driver/hive/HiveDriver.java |   5 +-
 .../driver/hive/HivePersistentResultSet.java    |   2 +-
 .../apache/lens/driver/hive/TestHiveDriver.java |   2 +-
 .../lens/server/api/LensConfConstants.java      |   8 +-
 .../server/api/driver/InMemoryResultSet.java    |  24 +-
 .../lens/server/api/driver/LensResultSet.java   |   9 +
 .../server/api/driver/PersistentResultSet.java  |  19 +-
 .../server/api/query/FinishedLensQuery.java     |   5 +-
 .../lens/server/api/query/QueryCancelled.java   |  10 +-
 .../lens/server/api/query/QueryClosed.java      |  10 +-
 .../lens/server/api/query/QueryContext.java     |   6 +-
 .../lens/server/api/query/QueryEnded.java       |   8 +-
 .../lens/server/api/query/QueryFailed.java      |  10 +-
 .../lens/server/api/query/QuerySuccess.java     |  10 +-
 .../lens/server/api/driver/MockDriver.java      |   9 +-
 .../lens/server/query/LensPersistentResult.java |  73 +++-
 .../lens/server/query/QueryEndNotifier.java     |  79 ++---
 .../server/query/QueryExecutionServiceImpl.java | 345 +++++++++----------
 .../QueryExecutionStatisticsGenerator.java      |  11 +-
 .../lens/server/query/ResultFormatter.java      |  17 +-
 .../src/main/resources/lensserver-default.xml   |   6 +-
 .../org/apache/lens/server/LensJerseyTest.java  |  21 +-
 .../lens/server/common/RestAPITestUtil.java     | 122 +++++--
 .../lens/server/query/TestEventService.java     |  11 +-
 .../server/query/TestQueryEndEmailNotifier.java | 196 +++++------
 .../lens/server/query/TestQueryService.java     | 253 +++++---------
 .../lens/server/query/TestResultFormatting.java |  11 +-
 lens-server/src/test/resources/lens-site.xml    |   6 +-
 src/site/apt/admin/config.apt                   |  42 +--
 36 files changed, 754 insertions(+), 647 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/LensConf.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/LensConf.java b/lens-api/src/main/java/org/apache/lens/api/LensConf.java
index 3b1ad87..ff965d6 100644
--- a/lens-api/src/main/java/org/apache/lens/api/LensConf.java
+++ b/lens-api/src/main/java/org/apache/lens/api/LensConf.java
@@ -63,11 +63,14 @@ public class LensConf implements Serializable {
     properties.put(key, value);
   }
 
+  public void addProperty(Object key, Object value) {
+    properties.put(String.valueOf(key), String.valueOf(value));
+  }
+
   /**
    * Adds Map of properties.
    *
-   * @param key   the key
-   * @param value the value
+   * @param props the properties
    */
   public void addProperties(Map<String, String> props) {
     properties.putAll(props);

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/query/InMemoryQueryResult.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/InMemoryQueryResult.java b/lens-api/src/main/java/org/apache/lens/api/query/InMemoryQueryResult.java
index 6a9f455..36d0ba0 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/InMemoryQueryResult.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/InMemoryQueryResult.java
@@ -27,10 +27,7 @@ import java.util.List;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
+import lombok.*;
 
 /**
  * The Class InMemoryQueryResult.
@@ -48,11 +45,26 @@ import lombok.NoArgsConstructor;
  */
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class InMemoryQueryResult extends QueryResult {
-
+  public static final String DECLARATION = "Result available in memory, attaching here: \n\n";
   /**
    * The rows.
    */
   @XmlElementWrapper
   @Getter
-  private List<ResultRow> rows = new ArrayList<ResultRow>();
+  private List<ResultRow> rows = new ArrayList<>();
+
+  public String toPrettyString() {
+    StringBuilder b = new StringBuilder();
+    b.append(DECLARATION);
+    int numRows = 0;
+    for (ResultRow row : getRows()) {
+      for (Object col : row.getValues()) {
+        b.append(col).append("\t");
+      }
+      numRows++;
+      b.append("\n");
+    }
+    b.append(numRows).append(" rows ");
+    return b.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java b/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java
index af439ff..204ecee 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/LensQuery.java
@@ -27,10 +27,7 @@ import javax.xml.bind.annotation.XmlRootElement;
 import org.apache.lens.api.LensConf;
 import org.apache.lens.api.Priority;
 
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
+import lombok.*;
 
 /**
  * The Class LensQuery.
@@ -81,6 +78,7 @@ import lombok.NoArgsConstructor;
  * Instantiates a new lens query.
  */
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
+@EqualsAndHashCode
 public class LensQuery {
 
   /**
@@ -214,7 +212,7 @@ public class LensQuery {
   }
 
   public String getErrorMessage() {
-    return (this.status!=null) ? this.status.getLensErrorTOErrorMsg() : null;
+    return (this.status != null) ? this.status.getLensErrorTOErrorMsg() : null;
   }
 
   public String getQueryHandleString() {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/query/PersistentQueryResult.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/PersistentQueryResult.java b/lens-api/src/main/java/org/apache/lens/api/query/PersistentQueryResult.java
index a2e10c6..cb72cdc 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/PersistentQueryResult.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/PersistentQueryResult.java
@@ -69,4 +69,22 @@ public class PersistentQueryResult extends QueryResult {
   @Getter
   private Long fileSize;
 
+  @XmlElement
+  @Getter
+  private String httpResultUrl;
+
+  @Override
+  public String toPrettyString() {
+    StringBuilder sb = new StringBuilder().append("Result available at ").append(persistedURI).append(".");
+    if (numRows != null) {
+      sb.append(" Number of rows: ").append(numRows).append(".");
+    }
+    if (fileSize != null) {
+      sb.append(" File size: ").append(fileSize).append(".");
+    }
+    if (httpResultUrl != null) {
+      sb.append(" Downloadable from ").append(httpResultUrl).append(".");
+    }
+    return sb.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/query/QueryResult.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryResult.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryResult.java
index 3ecf0c2..3bc7cc7 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryResult.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryResult.java
@@ -24,6 +24,8 @@ package org.apache.lens.api.query;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 
+import org.apache.lens.api.result.PrettyPrintable;
+
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
@@ -36,5 +38,5 @@ import lombok.NoArgsConstructor;
  * Instantiates a new query result.
  */
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
-public class QueryResult {
+public abstract class QueryResult implements PrettyPrintable {
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
index 3c8531f..91cbe39 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
@@ -264,6 +264,7 @@ public class QueryStatus implements Serializable {
       break;
     case EXECUTED:
       switch (newState) {
+      case EXECUTED:
       case SUCCESSFUL:
       case FAILED:
       case CANCELED:

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 006eaed..b6e3fcf 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -120,14 +120,7 @@ public class LensQueryCommands extends BaseLensCommand {
       QueryResult r = rs.getResultSet().getResult();
       if (r instanceof InMemoryQueryResult) {
         InMemoryQueryResult temp = (InMemoryQueryResult) r;
-        for (ResultRow row : temp.getRows()) {
-          for (Object col : row.getValues()) {
-            b.append(col).append("\t");
-          }
-          numRows++;
-          b.append("\n");
-        }
-        b.append(numRows + " rows ");
+        b.append(temp.toPrettyString());
       } else {
         PersistentQueryResult temp = (PersistentQueryResult) r;
         b.append("Results of query stored at : ").append(temp.getPersistedURI()).append("  ");

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
----------------------------------------------------------------------
diff --git a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
index 31c343a..4561ccf 100644
--- a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
+++ b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HiveDriver.java
@@ -842,7 +842,7 @@ public class HiveDriver implements LensDriver {
     log.info("Creating result set for hiveHandle:{}", op);
     try {
       if (context.isDriverPersistent()) {
-        return new HivePersistentResultSet(new Path(context.getHdfsoutPath()), op, getClient());
+        return new HivePersistentResultSet(new Path(context.getDriverResultPath()), op, getClient());
       } else if (op.hasResultSet()) {
         return new HiveInMemoryResultSet(op, getClient(), closeAfterFetch);
       } else {
@@ -874,7 +874,8 @@ public class HiveDriver implements LensDriver {
       Path resultSetPath = context.getHDFSResultDir();
       // create query
       StringBuilder builder = new StringBuilder("INSERT OVERWRITE DIRECTORY ");
-      context.setHdfsoutPath(resultSetPath.makeQualified(resultSetPath.getFileSystem(context.getConf())).toString());
+      context.setDriverResultPath(
+        resultSetPath.makeQualified(resultSetPath.getFileSystem(context.getConf())).toString());
       builder.append('"').append(resultSetPath).append("\" ");
       String outputDirFormat = qdconf.get(LensConfConstants.QUERY_OUTPUT_DIRECTORY_FORMAT);
       if (outputDirFormat != null) {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HivePersistentResultSet.java
----------------------------------------------------------------------
diff --git a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HivePersistentResultSet.java b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HivePersistentResultSet.java
index 00e1e53..746e17e 100644
--- a/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HivePersistentResultSet.java
+++ b/lens-driver-hive/src/main/java/org/apache/lens/driver/hive/HivePersistentResultSet.java
@@ -64,7 +64,7 @@ public class HivePersistentResultSet extends PersistentResultSet {
   }
 
   @Override
-  public Long fileSize() throws LensException {
+  public Long getFileSize() throws LensException {
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-driver-hive/src/test/java/org/apache/lens/driver/hive/TestHiveDriver.java
----------------------------------------------------------------------
diff --git a/lens-driver-hive/src/test/java/org/apache/lens/driver/hive/TestHiveDriver.java b/lens-driver-hive/src/test/java/org/apache/lens/driver/hive/TestHiveDriver.java
index 78b3320..2cb3736 100644
--- a/lens-driver-hive/src/test/java/org/apache/lens/driver/hive/TestHiveDriver.java
+++ b/lens-driver-hive/src/test/java/org/apache/lens/driver/hive/TestHiveDriver.java
@@ -793,7 +793,7 @@ public class TestHiveDriver {
     assertEquals(0, driver.getHiveHandleSize());
     HivePersistentResultSet persistentResultSet = (HivePersistentResultSet) resultSet;
     String path = persistentResultSet.getOutputPath();
-    assertEquals(ctx.getHdfsoutPath(), path);
+    assertEquals(ctx.getDriverResultPath(), path);
     driver.closeQuery(plan2.getHandle());
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index 096d26e..f202603 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -774,14 +774,14 @@ public final class LensConfConstants {
   // Query Purge Configuration
 
   /**
-   * The Constant MAX_NUMBER_OF_FINISHED_QUERY.
+   * The Constant PURGE_INTERVAL.
    */
-  public static final String MAX_NUMBER_OF_FINISHED_QUERY = SERVER_PFX + "max.finished.queries";
+  public static final String PURGE_INTERVAL = SERVER_PFX + "querypurger.sleep.interval";
 
   /**
-   * The Constant DEFAULT_FINISHED_QUERIES.
+   * The Constant DEFAULT_PURGE_INTERVAL.
    */
-  public static final int DEFAULT_FINISHED_QUERIES = 100;
+  public static final int DEFAULT_PURGE_INTERVAL = 10000;
 
   // Server DB configuration
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/driver/InMemoryResultSet.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/InMemoryResultSet.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/InMemoryResultSet.java
index 3b76126..c64a3dd 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/InMemoryResultSet.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/InMemoryResultSet.java
@@ -22,16 +22,31 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.lens.api.query.InMemoryQueryResult;
-import org.apache.lens.api.query.QueryResult;
 import org.apache.lens.api.query.ResultRow;
 import org.apache.lens.server.api.error.LensException;
 
+import lombok.Setter;
+
 /**
  * The Class InMemoryResultSet.
  */
 public abstract class InMemoryResultSet extends LensResultSet {
 
   public abstract boolean seekToStart() throws LensException;
+
+  @Setter
+  private boolean fullyAccessed = false;
+
+  @Override
+  public boolean canBePurged() {
+    return fullyAccessed;
+  }
+
+  @Override
+  public String getOutputPath() throws LensException {
+    return null;
+  }
+
   /**
    * Whether there is another result row available.
    *
@@ -60,12 +75,15 @@ public abstract class InMemoryResultSet extends LensResultSet {
    *
    * @see org.apache.lens.server.api.driver.LensResultSet#toQueryResult()
    */
-  public QueryResult toQueryResult() throws LensException {
+  public InMemoryQueryResult toQueryResult() throws LensException {
     List<ResultRow> rows = new ArrayList<ResultRow>();
     while (hasNext()) {
       rows.add(next());
     }
+    fullyAccessed = true;
     return new InMemoryQueryResult(rows);
   }
-
+  public boolean isHttpResultAvailable() throws LensException {
+    return false;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSet.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSet.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSet.java
index 929a302..805b0c1 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSet.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSet.java
@@ -25,6 +25,11 @@ import org.apache.lens.server.api.error.LensException;
  * Result set returned by driver.
  */
 public abstract class LensResultSet {
+  /**
+   *
+   * @return true if the result can be purged
+   */
+  public abstract boolean canBePurged();
 
   /**
    * Get the size of the result set.
@@ -39,8 +44,11 @@ public abstract class LensResultSet {
    *
    * @return Returns {@link LensResultSetMetadata}
    */
+
   public abstract LensResultSetMetadata getMetadata() throws LensException;
 
+  public abstract String getOutputPath() throws LensException;
+
   /**
    * Get the corresponding query result object.
    *
@@ -49,4 +57,5 @@ public abstract class LensResultSet {
    */
   public abstract QueryResult toQueryResult() throws LensException;
 
+  public abstract boolean isHttpResultAvailable() throws LensException;
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/driver/PersistentResultSet.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/PersistentResultSet.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/PersistentResultSet.java
index bbde170..774f1ee 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/PersistentResultSet.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/PersistentResultSet.java
@@ -19,7 +19,6 @@
 package org.apache.lens.server.api.driver;
 
 import org.apache.lens.api.query.PersistentQueryResult;
-import org.apache.lens.api.query.QueryResult;
 import org.apache.lens.server.api.error.LensException;
 
 /**
@@ -27,22 +26,32 @@ import org.apache.lens.server.api.error.LensException;
  */
 public abstract class PersistentResultSet extends LensResultSet {
 
+  @Override
+  public boolean canBePurged() {
+    return true;
+  }
+
   /**
    * Get the size of the result set file.
    *
    * @return The size if available, null if not available.
    * @throws LensException the lens exception
    */
-  public abstract Long fileSize() throws LensException;
+  public abstract Long getFileSize() throws LensException;
 
-  public abstract String getOutputPath() throws LensException;
+  public String getHttpResultUrl() {
+    return null;
+  }
 
   /*
    * (non-Javadoc)
    *
    * @see org.apache.lens.server.api.driver.LensResultSet#toQueryResult()
    */
-  public QueryResult toQueryResult() throws LensException {
-    return new PersistentQueryResult(getOutputPath(), size(), fileSize());
+  public PersistentQueryResult toQueryResult() throws LensException {
+    return new PersistentQueryResult(getOutputPath(), size(), getFileSize(), getHttpResultUrl());
+  }
+  public boolean isHttpResultAvailable() throws LensException {
+    return false;
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
index d8c04db..7a06c44 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
@@ -24,7 +24,6 @@ import org.apache.lens.api.LensConf;
 import org.apache.lens.api.query.QueryHandle;
 import org.apache.lens.api.query.QueryStatus;
 import org.apache.lens.server.api.driver.LensDriver;
-import org.apache.lens.server.api.error.LensException;
 import org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy;
 
 import org.apache.hadoop.conf.Configuration;
@@ -44,7 +43,7 @@ import lombok.ToString;
  *
  * @see java.lang.Object#hashCode()
  */
-@EqualsAndHashCode
+@EqualsAndHashCode(exclude = "selectedDriver")
 /*
  * (non-Javadoc)
  *
@@ -198,7 +197,7 @@ public class FinishedLensQuery {
     this.selectedDriver = ctx.getSelectedDriver();
   }
 
-  public QueryContext toQueryContext(Configuration conf, Collection<LensDriver> drivers) throws LensException {
+  public QueryContext toQueryContext(Configuration conf, Collection<LensDriver> drivers) {
     QueryContext qctx = new QueryContext(userQuery, submitter, new LensConf(), conf, drivers, null, submissionTime,
       false);
     qctx.setQueryHandle(QueryHandle.fromString(handle));

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryCancelled.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryCancelled.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryCancelled.java
index bc0465c..a473a47 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryCancelled.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryCancelled.java
@@ -29,6 +29,7 @@ public class QueryCancelled extends QueryEnded {
   /**
    * Instantiates a new query cancelled.
    *
+   * @param ctx       the query context
    * @param eventTime the event time
    * @param prev      the prev
    * @param current   the current
@@ -36,10 +37,15 @@ public class QueryCancelled extends QueryEnded {
    * @param user      the user
    * @param cause     the cause
    */
-  public QueryCancelled(long eventTime, QueryStatus.Status prev, QueryStatus.Status current, QueryHandle handle,
+  public QueryCancelled(QueryContext ctx, long eventTime, QueryStatus.Status prev, QueryStatus.Status current,
+    QueryHandle handle,
     String user, String cause) {
-    super(eventTime, prev, current, handle, user, cause);
+    super(ctx, eventTime, prev, current, handle, user, cause);
     checkCurrentState(QueryStatus.Status.CANCELED);
   }
 
+  public QueryCancelled(QueryContext ctx, QueryStatus.Status prevState, QueryStatus.Status currState, String cause) {
+    // TODO: correct username. put who cancelled it, not the submitter. Similar for others
+    this(ctx, ctx.getEndTime(), prevState, currState, ctx.getQueryHandle(), ctx.getSubmittedUser(), cause);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryClosed.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryClosed.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryClosed.java
index ea8f70f..3837087 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryClosed.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryClosed.java
@@ -29,6 +29,7 @@ public class QueryClosed extends QueryEnded {
   /**
    * Instantiates a new query closed.
    *
+   * @param ctx       the query context
    * @param eventTime the event time
    * @param prev      the prev
    * @param current   the current
@@ -36,9 +37,14 @@ public class QueryClosed extends QueryEnded {
    * @param user      the user
    * @param cause     the cause
    */
-  public QueryClosed(long eventTime, QueryStatus.Status prev, QueryStatus.Status current, QueryHandle handle,
+  public QueryClosed(QueryContext ctx, long eventTime, QueryStatus.Status prev, QueryStatus.Status current,
+    QueryHandle handle,
     String user, String cause) {
-    super(eventTime, prev, current, handle, user, cause);
+    super(ctx, eventTime, prev, current, handle, user, cause);
     checkCurrentState(QueryStatus.Status.CLOSED);
   }
+
+  public QueryClosed(QueryContext ctx, QueryStatus.Status prevState, QueryStatus.Status currState, String cause) {
+    this(ctx, ctx.getClosedTime(), prevState, currState, ctx.getQueryHandle(), ctx.getSubmittedUser(), cause);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index 12de0a5..bed79ac 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -42,10 +42,12 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import lombok.Getter;
 import lombok.Setter;
+import lombok.ToString;
 
 /**
  * The Class QueryContext.
  */
+@ToString
 public class QueryContext extends AbstractQueryContext {
 
   /**
@@ -95,7 +97,7 @@ public class QueryContext extends AbstractQueryContext {
    */
   @Getter
   @Setter
-  private String hdfsoutPath;
+  private String driverResultPath;
 
   /**
    * The submission time.
@@ -326,7 +328,7 @@ public class QueryContext extends AbstractQueryContext {
   /*
    * Introduced for Recovering finished query.
    */
-  public void setStatusSkippingTransitionTest(final QueryStatus newStatus) throws LensException {
+  public void setStatusSkippingTransitionTest(final QueryStatus newStatus) {
     this.status = newStatus;
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryEnded.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryEnded.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryEnded.java
index 3e9474c..e80da6d 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryEnded.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryEnded.java
@@ -33,6 +33,8 @@ import lombok.Getter;
  */
 public class QueryEnded extends StatusChange {
 
+  @Getter
+  private final QueryContext queryContext;
   /**
    * The user.
    */
@@ -54,6 +56,7 @@ public class QueryEnded extends StatusChange {
   /**
    * Instantiates a new query ended.
    *
+   * @param ctx
    * @param eventTime the event time
    * @param prev      the prev
    * @param current   the current
@@ -61,9 +64,10 @@ public class QueryEnded extends StatusChange {
    * @param user      the user
    * @param cause     the cause
    */
-  public QueryEnded(long eventTime, QueryStatus.Status prev, QueryStatus.Status current, QueryHandle handle,
-    String user, String cause) {
+  public QueryEnded(QueryContext ctx, long eventTime, QueryStatus.Status prev, QueryStatus.Status current,
+    QueryHandle handle, String user, String cause) {
     super(eventTime, prev, current, handle);
+    this.queryContext = ctx;
     this.user = user;
     this.cause = cause;
     if (!END_STATES.contains(current)) {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryFailed.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryFailed.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryFailed.java
index 40a1c0f..bdffbc2 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryFailed.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryFailed.java
@@ -29,6 +29,7 @@ public class QueryFailed extends QueryEnded {
   /**
    * Instantiates a new query failed.
    *
+   * @param ctx       the query context
    * @param eventTime the event time
    * @param prev      the prev
    * @param current   the current
@@ -36,9 +37,14 @@ public class QueryFailed extends QueryEnded {
    * @param user      the user
    * @param cause     the cause
    */
-  public QueryFailed(long eventTime, QueryStatus.Status prev, QueryStatus.Status current, QueryHandle handle,
+  public QueryFailed(QueryContext ctx, long eventTime, QueryStatus.Status prev, QueryStatus.Status current,
+    QueryHandle handle,
     String user, String cause) {
-    super(eventTime, prev, current, handle, user, cause);
+    super(ctx, eventTime, prev, current, handle, user, cause);
     checkCurrentState(QueryStatus.Status.FAILED);
   }
+
+  public QueryFailed(QueryContext ctx, QueryStatus.Status prevState, QueryStatus.Status currState, String cause) {
+    this(ctx, ctx.getEndTime(), prevState, currState, ctx.getQueryHandle(), ctx.getSubmittedUser(), cause);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/main/java/org/apache/lens/server/api/query/QuerySuccess.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QuerySuccess.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QuerySuccess.java
index c551dba..298fdbb 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QuerySuccess.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QuerySuccess.java
@@ -29,13 +29,19 @@ public class QuerySuccess extends QueryEnded {
   /**
    * Instantiates a new query success.
    *
+   * @param ctx       the query context
    * @param eventTime the event time
    * @param prev      the prev
    * @param current   the current
    * @param handle    the handle
    */
-  public QuerySuccess(long eventTime, QueryStatus.Status prev, QueryStatus.Status current, QueryHandle handle) {
-    super(eventTime, prev, current, handle, null, null);
+  public QuerySuccess(QueryContext ctx, long eventTime, QueryStatus.Status prev, QueryStatus.Status current,
+    QueryHandle handle) {
+    super(ctx, eventTime, prev, current, handle, null, null);
     checkCurrentState(QueryStatus.Status.SUCCESSFUL);
   }
+
+  public QuerySuccess(QueryContext ctx, QueryStatus.Status prevState, QueryStatus.Status currState) {
+    this(ctx, ctx.getEndTime(), prevState, currState, ctx.getQueryHandle());
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server-api/src/test/java/org/apache/lens/server/api/driver/MockDriver.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/test/java/org/apache/lens/server/api/driver/MockDriver.java b/lens-server-api/src/test/java/org/apache/lens/server/api/driver/MockDriver.java
index b28669e..2d86589 100644
--- a/lens-server-api/src/test/java/org/apache/lens/server/api/driver/MockDriver.java
+++ b/lens-server-api/src/test/java/org/apache/lens/server/api/driver/MockDriver.java
@@ -255,7 +255,7 @@ public class MockDriver implements LensDriver {
       }
 
       @Override
-      public Long fileSize() throws LensException {
+      public Long getFileSize() throws LensException {
         // TODO Auto-generated method stub
         return null;
       }
@@ -297,7 +297,7 @@ public class MockDriver implements LensDriver {
    * @see org.apache.lens.server.api.driver.LensDriver#fetchResultSet(org.apache.lens.server.api.query.QueryContext)
    */
   @Override
-  public LensResultSet fetchResultSet(QueryContext context) throws LensException {
+  public LensResultSet fetchResultSet(final QueryContext context) throws LensException {
     return new InMemoryResultSet() {
 
       @Override
@@ -340,6 +340,11 @@ public class MockDriver implements LensDriver {
         // TODO Auto-generated method stub
         return false;
       }
+
+      @Override
+      public boolean canBePurged() {
+        return true;
+      }
     };
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java b/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
index b65a5f4..1e9a182 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
@@ -18,13 +18,27 @@
  */
 package org.apache.lens.server.query;
 
+import java.io.IOException;
+
+import org.apache.lens.api.query.QueryHandle;
+import org.apache.lens.server.api.LensConfConstants;
 import org.apache.lens.server.api.driver.LensResultSetMetadata;
 import org.apache.lens.server.api.driver.PersistentResultSet;
 import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.FinishedLensQuery;
+import org.apache.lens.server.api.query.QueryContext;
 
-/**
- * The Class LensPersistentResult.
- */
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import org.codehaus.jackson.map.ObjectMapper;
+
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+/** The Class LensPersistentResult. */
+@Slf4j
 public class LensPersistentResult extends PersistentResultSet {
 
   /** The metadata. */
@@ -38,19 +52,45 @@ public class LensPersistentResult extends PersistentResultSet {
 
   /** The file size. */
   private final Long fileSize;
+  private final Configuration conf;
+  @Getter
+  private String httpResultUrl = null;
 
   /**
    * Instantiates a new lens persistent result.
-   *
-   * @param metadata   the metadata
-   * @param outputPath the output path
-   * @param numRows    the num rows
+   *  @param queryHandle the query handle
+   * @param metadata    the metadata
+   * @param outputPath  the output path
+   * @param numRows     the num rows
+   * @param conf        the lens server conf
    */
-  public LensPersistentResult(LensResultSetMetadata metadata, String outputPath, Integer numRows, Long fileSize) {
+  public LensPersistentResult(QueryHandle queryHandle, LensResultSetMetadata metadata, String outputPath, Integer
+    numRows, Long fileSize,
+    Configuration conf) {
     this.metadata = metadata;
     this.outputPath = outputPath;
     this.numRows = numRows;
     this.fileSize = fileSize;
+    this.conf = conf;
+    if (isHttpResultAvailable()) {
+      this.httpResultUrl = conf.get(LensConfConstants.SERVER_BASE_URL, LensConfConstants.DEFAULT_SERVER_BASE_URL)
+        + "queryapi/queries/" + queryHandle + "/httpresultset";
+    }
+  }
+
+  public LensPersistentResult(QueryContext ctx, Configuration conf) {
+    this(ctx.getQueryHandle(),
+      ctx.getQueryOutputFormatter().getMetadata(),
+      ctx.getQueryOutputFormatter().getFinalOutputPath(),
+      ctx.getQueryOutputFormatter().getNumRows(),
+      ctx.getQueryOutputFormatter().getFileSize(), conf);
+  }
+
+  public LensPersistentResult(FinishedLensQuery query, Configuration conf, ObjectMapper mapper) throws
+    ClassNotFoundException, IOException {
+    this(QueryHandle.fromString(query.getHandle()),
+      mapper.readValue(query.getMetadata(), (Class<LensResultSetMetadata>) Class.forName(query.getMetadataClass())),
+      query.getResult(), query.getRows(), query.getFileSize(), conf);
   }
 
   @Override
@@ -69,7 +109,7 @@ public class LensPersistentResult extends PersistentResultSet {
   }
 
   @Override
-  public Long fileSize() throws LensException {
+  public Long getFileSize() throws LensException {
     return fileSize;
   }
 
@@ -77,4 +117,19 @@ public class LensPersistentResult extends PersistentResultSet {
   public LensResultSetMetadata getMetadata() throws LensException {
     return metadata;
   }
+
+  @Override
+  public boolean isHttpResultAvailable() {
+    try {
+      final Path resultPath = new Path(getOutputPath());
+      FileSystem fs = resultPath.getFileSystem(conf);
+      if (fs.isDirectory(resultPath)) {
+        return false;
+      }
+    } catch (IOException | LensException e) {
+      log.warn("Unable to get status for Result Directory", e);
+      return false;
+    }
+    return true;
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/java/org/apache/lens/server/query/QueryEndNotifier.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryEndNotifier.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryEndNotifier.java
index 45ba7ac..110624a 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryEndNotifier.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryEndNotifier.java
@@ -18,6 +18,8 @@
  */
 package org.apache.lens.server.query;
 
+import static org.apache.lens.server.api.LensConfConstants.*;
+
 import java.util.Date;
 import java.util.Properties;
 
@@ -32,7 +34,7 @@ import javax.mail.internet.MimeMultipart;
 
 import org.apache.lens.api.query.QueryStatus;
 import org.apache.lens.server.LensServices;
-import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.error.LensException;
 import org.apache.lens.server.api.events.AsyncEventListener;
 import org.apache.lens.server.api.metrics.MetricsService;
 import org.apache.lens.server.api.query.QueryContext;
@@ -58,9 +60,6 @@ public class QueryEndNotifier extends AsyncEventListener<QueryEnded> {
   /** The Constant EMAIL_ERROR_COUNTER. */
   public static final String EMAIL_ERROR_COUNTER = "email-send-errors";
 
-  /** The conf. */
-  private final HiveConf conf;
-
   /** The from. */
   private final String from;
 
@@ -78,37 +77,33 @@ public class QueryEndNotifier extends AsyncEventListener<QueryEnded> {
 
   private final LogSegregationContext logSegregationContext;
 
-  /**
-   * Instantiates a new query end notifier.
+  /** Instantiates a new query end notifier.
    *
    * @param queryService the query service
-   * @param hiveConf     the hive conf
-   */
+   * @param hiveConf     the hive conf */
   public QueryEndNotifier(QueryExecutionServiceImpl queryService, HiveConf hiveConf,
-      @NonNull final LogSegregationContext logSegregationContext) {
+    @NonNull final LogSegregationContext logSegregationContext) {
     this.queryService = queryService;
-    this.conf = hiveConf;
-    from = conf.get(LensConfConstants.MAIL_FROM_ADDRESS);
-    host = conf.get(LensConfConstants.MAIL_HOST);
-    port = conf.get(LensConfConstants.MAIL_PORT);
-    mailSmtpTimeout = Integer.parseInt(
-        conf.get(LensConfConstants.MAIL_SMTP_TIMEOUT, LensConfConstants.MAIL_DEFAULT_SMTP_TIMEOUT));
-    mailSmtpConnectionTimeout = Integer.parseInt(conf.get(LensConfConstants.MAIL_SMTP_CONNECTIONTIMEOUT,
-      LensConfConstants.MAIL_DEFAULT_SMTP_CONNECTIONTIMEOUT));
+    HiveConf conf = hiveConf;
+    from = conf.get(MAIL_FROM_ADDRESS);
+    host = conf.get(MAIL_HOST);
+    port = conf.get(MAIL_PORT);
+    mailSmtpTimeout = Integer.parseInt(conf.get(MAIL_SMTP_TIMEOUT, MAIL_DEFAULT_SMTP_TIMEOUT));
+    mailSmtpConnectionTimeout = Integer.parseInt(conf.get(MAIL_SMTP_CONNECTIONTIMEOUT,
+      MAIL_DEFAULT_SMTP_CONNECTIONTIMEOUT));
     this.logSegregationContext = logSegregationContext;
   }
 
   /*
    * (non-Javadoc)
    *
-   * @see org.apache.lens.server.api.events.AsyncEventListener#process(org.apache.lens.server.api.events.LensEvent)
-   */
+   * @see org.apache.lens.server.api.events.AsyncEventListener#process(org.apache.lens.server.api.events.LensEvent) */
   @Override
-  public void process(QueryEnded event) {
+  public void process(final QueryEnded event) {
     if (event.getCurrentValue() == QueryStatus.Status.CLOSED) {
       return;
     }
-    QueryContext queryContext = queryService.getQueryContext(event.getQueryHandle());
+    QueryContext queryContext = event.getQueryContext();
     if (queryContext == null) {
       log.warn("Could not find the context for {} for event:{}. No email generated", event.getQueryHandle(),
         event.getCurrentValue());
@@ -116,45 +111,36 @@ public class QueryEndNotifier extends AsyncEventListener<QueryEnded> {
     }
     this.logSegregationContext.setLogSegragationAndQueryId(queryContext.getQueryHandleString());
 
-    boolean whetherMailNotify = Boolean.parseBoolean(queryContext.getConf().get(LensConfConstants.QUERY_MAIL_NOTIFY,
-      LensConfConstants.WHETHER_MAIL_NOTIFY_DEFAULT));
+    boolean whetherMailNotify = Boolean.parseBoolean(queryContext.getConf().get(QUERY_MAIL_NOTIFY,
+      WHETHER_MAIL_NOTIFY_DEFAULT));
 
     if (!whetherMailNotify) {
       return;
     }
 
     String queryName = queryContext.getQueryName();
-    queryName = queryName == null ? "" : queryName;
-    String mailSubject = "Query " + queryName + " " + queryContext.getStatus().getStatus() + ": "
-      + event.getQueryHandle();
+    String mailSubject = "Query " + (StringUtils.isBlank(queryName) ? "" : (queryName + " "))
+      + queryContext.getStatus().getStatus() + ": " + event.getQueryHandle();
 
     String mailMessage = createMailMessage(queryContext);
 
     String to = queryContext.getSubmittedUser() + "@" + queryService.getServerDomain();
 
-    String cc = queryContext.getConf().get(LensConfConstants.QUERY_RESULT_EMAIL_CC,
-      LensConfConstants.QUERY_RESULT_DEFAULT_EMAIL_CC);
+    String cc = queryContext.getConf().get(QUERY_RESULT_EMAIL_CC, QUERY_RESULT_DEFAULT_EMAIL_CC);
 
     log.info("Sending completion email for query handle: {}", event.getQueryHandle());
     sendMail(host, port, new Email(from, to, cc, mailSubject, mailMessage), mailSmtpTimeout, mailSmtpConnectionTimeout);
   }
 
-  /**
-   * Creates the mail message.
+  /** Creates the mail message.
    *
    * @param queryContext the query context
-   * @return the string
-   */
+   * @return the string */
   private String createMailMessage(QueryContext queryContext) {
     StringBuilder msgBuilder = new StringBuilder();
     switch (queryContext.getStatus().getStatus()) {
     case SUCCESSFUL:
-      msgBuilder.append("Result available at ");
-      String baseURI = conf.get(LensConfConstants.SERVER_BASE_URL, LensConfConstants.DEFAULT_SERVER_BASE_URL);
-      msgBuilder.append(baseURI);
-      msgBuilder.append("queryapi/queries/");
-      msgBuilder.append(queryContext.getQueryHandle());
-      msgBuilder.append("/httpresultset");
+      msgBuilder.append(getResultMessage(queryContext));
       break;
     case FAILED:
       msgBuilder.append(queryContext.getStatus().getStatusMessage());
@@ -166,13 +152,21 @@ public class QueryEndNotifier extends AsyncEventListener<QueryEnded> {
     case CANCELED:
       msgBuilder.append(queryContext.getStatus().getStatusMessage());
       break;
-    case CLOSED:
     default:
       break;
     }
     return msgBuilder.toString();
   }
 
+  private String getResultMessage(QueryContext queryContext) {
+    try {
+      return queryService.getResultset(queryContext.getQueryHandle()).toQueryResult().toPrettyString();
+    } catch (LensException e) {
+      log.error("Error retrieving result of query handle {} for sending e-mail", queryContext.getQueryHandle(), e);
+      return "Error retrieving result.";
+    }
+  }
+
   @Data
   public static class Email {
     private final String from;
@@ -181,15 +175,14 @@ public class QueryEndNotifier extends AsyncEventListener<QueryEnded> {
     private final String subject;
     private final String message;
   }
-  /**
-   * Send mail.
+
+  /** Send mail.
    *
    * @param host                      the host
    * @param port                      the port
    * @param email                     the email
    * @param mailSmtpTimeout           the mail smtp timeout
-   * @param mailSmtpConnectionTimeout the mail smtp connection timeout
-   */
+   * @param mailSmtpConnectionTimeout the mail smtp connection timeout */
   public static void sendMail(String host, String port,
     Email email, int mailSmtpTimeout, int mailSmtpConnectionTimeout) {
     Properties props = System.getProperties();

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 9e27dd4..2ba54e0 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -88,10 +88,12 @@ import org.codehaus.jackson.map.module.SimpleModule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import lombok.Getter;
 import lombok.NonNull;
+import lombok.ToString;
 import lombok.extern.slf4j.Slf4j;
 
 /**
@@ -159,18 +161,17 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   /**
    * The finished queries.
    */
-  private DelayQueue<FinishedQuery> finishedQueries = new DelayQueue<FinishedQuery>();
+  ConcurrentLinkedQueue<FinishedQuery> finishedQueries = new ConcurrentLinkedQueue<>();
 
   /**
    * The prepared query queue.
    */
-  private DelayQueue<PreparedQueryContext> preparedQueryQueue = new DelayQueue<PreparedQueryContext>();
+  private DelayQueue<PreparedQueryContext> preparedQueryQueue = new DelayQueue<>();
 
   /**
    * The prepared queries.
    */
-  private Map<QueryPrepareHandle, PreparedQueryContext> preparedQueries
-    = new HashMap<QueryPrepareHandle, PreparedQueryContext>();
+  private Map<QueryPrepareHandle, PreparedQueryContext> preparedQueries = new HashMap<>();
 
   /**
    * The all queries.
@@ -180,7 +181,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   /**
    * The conf.
    */
-  private Configuration conf;
+  @VisibleForTesting
+  Configuration conf;
 
   /**
    * The query submitter runnable.
@@ -240,7 +242,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   /**
    * The max finished queries.
    */
-  private int maxFinishedQueries;
+  int purgeInterval;
 
   /**
    * The lens server dao.
@@ -328,7 +330,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     }
     // Add result formatter
     getEventService().addListenerForType(new ResultFormatter(this, this.logSegregationContext), QueryExecuted.class);
-    getEventService().addListenerForType(new QueryExecutionStatisticsGenerator(this, getEventService()),
+    getEventService().addListenerForType(new QueryExecutionStatisticsGenerator(getEventService()),
       QueryEnded.class);
     getEventService().addListenerForType(
       new QueryEndNotifier(this, getCliService().getHiveConf(), this.logSegregationContext), QueryEnded.class);
@@ -435,11 +437,13 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   /**
    * The Class FinishedQuery.
    */
-  private class FinishedQuery implements Delayed {
+  @ToString
+  public class FinishedQuery {
 
     /**
      * The ctx.
      */
+    @Getter
     private final QueryContext ctx;
 
     /**
@@ -462,29 +466,25 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       }
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.lang.Comparable#compareTo(java.lang.Object)
-     */
-    @Override
-    public int compareTo(Delayed o) {
-      return (int) (this.finishTime.getTime() - ((FinishedQuery) o).finishTime.getTime());
+    public boolean canBePurged() {
+      try {
+        if (getCtx().getStatus().getStatus().equals(SUCCESSFUL)) {
+          if (getCtx().getStatus().isResultSetAvailable()) {
+            LensResultSet rs = getResultset();
+            log.info("Resultset for {} is {}", getQueryHandle(), rs);
+            return rs.canBePurged();
+          }
+        }
+        return true;
+      } catch (Throwable e) {
+        log.error("Error while accessing result set for query handle while purging: {}."
+          + " Hence, going ahead with purge", getQueryHandle(), e);
+        return true;
+      }
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see java.util.concurrent.Delayed#getDelay(java.util.concurrent.TimeUnit)
-     */
-    @Override
-    public long getDelay(TimeUnit units) {
-      int size = finishedQueries.size();
-      if (size > maxFinishedQueries) {
-        return 0;
-      } else {
-        return Integer.MAX_VALUE;
-      }
+    private LensResultSet getResultset() throws LensException {
+      return QueryExecutionServiceImpl.this.getResultset(getQueryHandle());
     }
 
     /**
@@ -494,16 +494,13 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       return finishTime;
     }
 
-    /**
-     * @return the ctx
-     */
-    public QueryContext getCtx() {
-      return ctx;
-    }
-
     public String getQueryHandleString() {
       return ctx.getQueryHandleString();
     }
+
+    public QueryHandle getQueryHandle() {
+      return ctx.getQueryHandle();
+    }
   }
 
   /**
@@ -523,8 +520,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     private final QueryLaunchingConstraintsChecker constraintsChecker;
 
     public QuerySubmitter(@NonNull final ErrorCollection errorCollection,
-        @NonNull final EstimatedQueryCollection waitingQueries,
-        @NonNull final QueryLaunchingConstraintsChecker constraintsChecker) {
+      @NonNull final EstimatedQueryCollection waitingQueries,
+      @NonNull final QueryLaunchingConstraintsChecker constraintsChecker) {
 
       this.errorCollection = errorCollection;
       this.waitingQueries = waitingQueries;
@@ -639,9 +636,9 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     }
 
     private void checkEstimatedQueriesState(final QueryContext query) throws LensException {
-      if  (query.getSelectedDriver() == null || query.getSelectedDriverQueryCost() == null) {
-        throw new LensException("selected driver: " + query.getSelectedDriver()  +" OR selected driver query cost: "
-            + query.getSelectedDriverQueryCost() + " is null. Query doesn't appear to be an estimated query.");
+      if (query.getSelectedDriver() == null || query.getSelectedDriverQueryCost() == null) {
+        throw new LensException("selected driver: " + query.getSelectedDriver() + " OR selected driver query cost: "
+          + query.getSelectedDriverQueryCost() + " is null. Query doesn't appear to be an estimated query.");
       }
     }
   }
@@ -789,10 +786,9 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             ctx.setStatus(ctx.getDriverStatus().toQueryStatus());
           } catch (LensException exc) {
             // Driver gave exception while updating status
-
             setFailedStatus(ctx, "Status update failed", exc.getMessage(), exc.buildLensErrorTO(this.errorCollection));
             log.error("Status update failed for {}", handle, exc);
-
+            return;
           }
           // query is successfully executed by driver and
           // if query result need not be persisted or there is no result available in driver, move the query to
@@ -832,10 +828,9 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     QueryHandle query = ctx.getQueryHandle();
     switch (currState) {
     case CANCELED:
-      // TODO: correct username. put who cancelled it, not the submitter. Similar for others
-      return new QueryCancelled(ctx.getEndTime(), prevState, currState, query, ctx.getSubmittedUser(), null);
+      return new QueryCancelled(ctx, prevState, currState, null);
     case CLOSED:
-      return new QueryClosed(ctx.getClosedTime(), prevState, currState, query, ctx.getSubmittedUser(), null);
+      return new QueryClosed(ctx, prevState, currState, null);
     case FAILED:
       StringBuilder msgBuilder = new StringBuilder();
       msgBuilder.append(ctx.getStatus().getStatusMessage());
@@ -843,8 +838,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
         msgBuilder.append("\n Reason:\n");
         msgBuilder.append(ctx.getStatus().getErrorMessage());
       }
-      return new QueryFailed(ctx.getEndTime(), prevState, currState, query, ctx.getSubmittedUser(),
-        msgBuilder.toString());
+      return new QueryFailed(ctx, prevState, currState, msgBuilder.toString());
     case LAUNCHED:
       return new QueryLaunched(ctx.getLaunchTime(), prevState, currState, query);
     case QUEUED:
@@ -855,7 +849,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     case EXECUTED:
       return new QueryExecuted(ctx.getDriverStatus().getDriverFinishTime(), prevState, currState, query);
     case SUCCESSFUL:
-      return new QuerySuccess(ctx.getEndTime(), prevState, currState, query);
+      return new QuerySuccess(ctx, prevState, currState);
     default:
       log.warn("Query {} transitioned to {} state from {} state", query, currState, prevState);
       return null;
@@ -905,64 +899,67 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     public void run() {
       log.info("Starting Query purger thread");
       while (!stopped && !queryPurger.isInterrupted()) {
-        FinishedQuery finished = null;
         try {
-          finished = finishedQueries.take();
-          logSegregationContext.setLogSegragationAndQueryId(finished.getQueryHandleString());
-        } catch (InterruptedException e) {
-          log.info("QueryPurger has been interrupted, exiting");
-          return;
-        }
-        try {
-          FinishedLensQuery finishedQuery = new FinishedLensQuery(finished.getCtx());
-          if (finished.ctx.getStatus().getStatus() == SUCCESSFUL) {
-            if (finished.ctx.getStatus().isResultSetAvailable()) {
-              LensResultSet set = getResultset(finished.getCtx().getQueryHandle());
-              if (set != null && PersistentResultSet.class.isAssignableFrom(set.getClass())) {
-                LensResultSetMetadata metadata = set.getMetadata();
-                String outputPath = ((PersistentResultSet) set).getOutputPath();
-                Long fileSize = ((PersistentResultSet) set).fileSize();
-                Integer rows = set.size();
-                finishedQuery.setMetadataClass(metadata.getClass().getName());
-                finishedQuery.setResult(outputPath);
-                finishedQuery.setMetadata(MAPPER.writeValueAsString(metadata));
-                finishedQuery.setRows(rows);
-                finishedQuery.setFileSize(fileSize);
+          Iterator<FinishedQuery> iter = finishedQueries.iterator();
+          FinishedQuery finished;
+          while (iter.hasNext()) {
+            finished = iter.next();
+            if (finished.canBePurged()) {
+              try {
+                FinishedLensQuery finishedQuery = new FinishedLensQuery(finished.getCtx());
+                if (finished.ctx.getStatus().getStatus() == SUCCESSFUL) {
+                  if (finished.ctx.getStatus().isResultSetAvailable()) {
+                    try {
+                      LensResultSet set = finished.getResultset();
+                      if (set != null && PersistentResultSet.class.isAssignableFrom(set.getClass())) {
+                        LensResultSetMetadata metadata = set.getMetadata();
+                        String outputPath = set.getOutputPath();
+                        Long fileSize = ((PersistentResultSet) set).getFileSize();
+                        Integer rows = set.size();
+                        finishedQuery.setMetadataClass(metadata.getClass().getName());
+                        finishedQuery.setResult(outputPath);
+                        finishedQuery.setMetadata(MAPPER.writeValueAsString(metadata));
+                        finishedQuery.setRows(rows);
+                        finishedQuery.setFileSize(fileSize);
+                      }
+                    } catch (Exception e) {
+                      log.error("Couldn't obtain result set info for the query: {}. Going ahead with purge",
+                        finished.getQueryHandle(), e);
+                    }
+                  }
+                }
+                lensServerDao.insertFinishedQuery(finishedQuery);
+                log.info("Saved query {} to DB", finishedQuery.getHandle());
+                iter.remove();
+              } catch (Exception e) {
+                log.warn("Exception while purging query {}", finished.getQueryHandle(), e);
+                continue;
               }
-            }
-          }
-          try {
-            lensServerDao.insertFinishedQuery(finishedQuery);
-            log.info("Saved query {} to DB", finishedQuery.getHandle());
-          } catch (Exception e) {
-            log.warn("Exception while purging query ", e);
-            finishedQueries.add(finished);
-            continue;
-          }
-
-          synchronized (finished.ctx) {
-            finished.ctx.setFinishedQueryPersisted(true);
-            try {
-              if (finished.getCtx().getSelectedDriver() != null) {
-                finished.getCtx().getSelectedDriver().closeQuery(finished.getCtx().getQueryHandle());
+              synchronized (finished.ctx) {
+                finished.ctx.setFinishedQueryPersisted(true);
+                try {
+                  if (finished.getCtx().getSelectedDriver() != null) {
+                    finished.getCtx().getSelectedDriver().closeQuery(finished.getQueryHandle());
+                  }
+                } catch (Exception e) {
+                  log.warn("Exception while closing query with selected driver.", e);
+                }
+                log.info("Purging: {}", finished.getQueryHandle());
+                allQueries.remove(finished.getQueryHandle());
+                resultSets.remove(finished.getQueryHandle());
               }
-            } catch (Exception e) {
-              log.warn("Exception while closing query with selected driver.", e);
+              fireStatusChangeEvent(finished.getCtx(),
+                new QueryStatus(1f, null, CLOSED, "Query purged", false, null, null, null), finished.getCtx()
+                  .getStatus());
+              log.info("Query purged: {}", finished.getQueryHandle());
             }
-            log.info("Purging: {}", finished.getCtx().getQueryHandle());
-            allQueries.remove(finished.getCtx().getQueryHandle());
-            resultSets.remove(finished.getCtx().getQueryHandle());
           }
-          fireStatusChangeEvent(finished.getCtx(),
-            new QueryStatus(1f, null, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
-          log.info("Query purged: {}", finished.getCtx().getQueryHandle());
-
-        } catch (LensException e) {
-          incrCounter(QUERY_PURGER_COUNTER);
-          log.error("Error closing  query ", e);
-        } catch (Exception e) {
+          Thread.sleep(purgeInterval);
+        } catch (InterruptedException e) {
+          log.error("purger interrupted", e);
+        } catch (Throwable e) {
+          log.error("Purger giving error", e);
           incrCounter(QUERY_PURGER_COUNTER);
-          log.error("Error in query purger", e);
         }
       }
       log.info("QueryPurger exited");
@@ -1018,16 +1015,16 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       new DefaultQueryCollection(new TreeSet<QueryContext>(new QueryContextPriorityComparator()))));
 
     ImmutableSet<QueryLaunchingConstraint> queryConstraints = getImplementations(
-        QUERY_LAUNCHING_CONSTRAINT_FACTORIES_KEY, hiveConf);
+      QUERY_LAUNCHING_CONSTRAINT_FACTORIES_KEY, hiveConf);
 
     this.queryConstraintsChecker = new DefaultQueryLaunchingConstraintsChecker(queryConstraints);
 
     this.querySubmitterRunnable = new QuerySubmitter(LensServices.get().getErrorCollection(), this.waitingQueries,
-        this.queryConstraintsChecker);
+      this.queryConstraintsChecker);
     this.querySubmitter = new Thread(querySubmitterRunnable, "QuerySubmitter");
 
     ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies = getImplementations(
-        WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY, hiveConf);
+      WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY, hiveConf);
 
     this.waitingQueriesSelector = new IntersectingWaitingQueriesSelector(selectionPolicies);
 
@@ -1048,8 +1045,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       log.error("Error while loading drivers", e);
       throw new IllegalStateException("Could not load drivers", e);
     }
-    maxFinishedQueries = conf.getInt(MAX_NUMBER_OF_FINISHED_QUERY,
-      DEFAULT_FINISHED_QUERIES);
+    purgeInterval = conf.getInt(PURGE_INTERVAL, DEFAULT_PURGE_INTERVAL);
     initalizeFinishedQueryStore(conf);
     log.info("Query execution service initialized");
   }
@@ -1207,7 +1203,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    */
   private void rewriteAndSelect(final AbstractQueryContext ctx) throws LensException {
     MethodMetricsContext parallelCallGauge = MethodMetricsFactory.createMethodGauge(ctx.getConf(), false,
-        PARALLEL_CALL_GAUGE);
+      PARALLEL_CALL_GAUGE);
     try {
       userQueryToCubeQueryRewriter.rewrite(ctx);
       // Initially we obtain individual runnables for rewrite and estimate calls
@@ -1293,7 +1289,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       }
 
       MethodMetricsContext selectGauge = MethodMetricsFactory.createMethodGauge(ctx.getConf(), false,
-          DRIVER_SELECTOR_GAUGE);
+        DRIVER_SELECTOR_GAUGE);
       // 2. select driver to run the query
       LensDriver driver = driverSelector.select(ctx, conf);
       ctx.setSelectedDriver(driver);
@@ -1420,16 +1416,14 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    * @return the resultset from dao
    * @throws LensException the lens exception
    */
-  private LensResultSet getResultsetFromDAO(QueryHandle queryHandle) throws LensException {
+  private LensPersistentResult getResultsetFromDAO(QueryHandle queryHandle) throws LensException {
     FinishedLensQuery query = lensServerDao.getQuery(queryHandle.toString());
     if (query != null) {
       if (query.getResult() == null) {
         throw new NotFoundException("InMemory Query result purged " + queryHandle);
       }
       try {
-        Class<LensResultSetMetadata> mdKlass = (Class<LensResultSetMetadata>) Class.forName(query.getMetadataClass());
-        return new LensPersistentResult(MAPPER.readValue(query.getMetadata(), mdKlass), query.getResult(),
-          query.getRows(), query.getFileSize());
+        return new LensPersistentResult(query, conf, MAPPER);
       } catch (Exception e) {
         throw new LensException(e);
       }
@@ -1444,7 +1438,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    * @return the resultset
    * @throws LensException the lens exception
    */
-  private LensResultSet getResultset(QueryHandle queryHandle) throws LensException {
+  LensResultSet getResultset(QueryHandle queryHandle) throws LensException {
     QueryContext ctx = allQueries.get(queryHandle);
     if (ctx == null) {
       return getResultsetFromDAO(queryHandle);
@@ -1456,15 +1450,9 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
         LensResultSet resultSet = resultSets.get(queryHandle);
         if (resultSet == null) {
           if (ctx.isPersistent() && ctx.getQueryOutputFormatter() != null) {
-            resultSets
-              .put(queryHandle,
-                new LensPersistentResult(
-                  ctx.getQueryOutputFormatter().getMetadata(),
-                  ctx.getQueryOutputFormatter().getFinalOutputPath(),
-                  ctx.getQueryOutputFormatter().getNumRows(),
-                  ctx.getQueryOutputFormatter().getFileSize()));
+            resultSets.put(queryHandle, new LensPersistentResult(ctx, conf));
           } else if (allQueries.get(queryHandle).isResultAvailableInDriver()) {
-            resultSet = allQueries.get(queryHandle).getSelectedDriver().fetchResultSet(allQueries.get(queryHandle));
+            resultSet = getDriverResultset(queryHandle);
             resultSets.put(queryHandle, resultSet);
           } else {
             throw new NotFoundException("Result set not available for query:" + queryHandle);
@@ -1585,7 +1573,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public QueryHandle executePrepareAsync(LensSessionHandle sessionHandle, QueryPrepareHandle prepareHandle,
     LensConf conf, String queryName) throws LensException {
     try {
-      log.info("ExecutePrepareAsync: session:{} prepareHandle:{}", sessionHandle,  prepareHandle.getPrepareHandleId());
+      log.info("ExecutePrepareAsync: session:{} prepareHandle:{}", sessionHandle, prepareHandle.getPrepareHandleId());
       acquire(sessionHandle);
       PreparedQueryContext pctx = getPreparedQueryContext(sessionHandle, prepareHandle);
       Configuration qconf = getLensConf(sessionHandle, conf);
@@ -1771,13 +1759,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       acquire(sessionHandle);
       QueryContext ctx = allQueries.get(queryHandle);
       if (ctx == null) {
-        FinishedLensQuery query = lensServerDao.getQuery(queryHandle.toString());
-        log.info("FinishedLensQuery:{}", query);
-        if (query == null) {
-          throw new NotFoundException("Query not found " + queryHandle);
-        }
-        // pass the query conf instead of service conf
-        return query.toQueryContext(conf, drivers.values());
+        return getQueryContextOfFinishedQuery(queryHandle);
       }
       updateStatus(queryHandle);
       return ctx;
@@ -1786,6 +1768,16 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     }
   }
 
+  QueryContext getQueryContextOfFinishedQuery(QueryHandle queryHandle) {
+    FinishedLensQuery query = lensServerDao.getQuery(queryHandle.toString());
+    log.info("FinishedLensQuery:{}", query);
+    if (query == null) {
+      throw new NotFoundException("Query not found " + queryHandle);
+    }
+    // pass the query conf instead of service conf
+    return query.toQueryContext(conf, drivers.values());
+  }
+
   /**
    * Gets the query context.
    *
@@ -1981,6 +1973,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
         this.notify();
       }
     }
+
   }
 
   /*
@@ -1994,7 +1987,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public QueryResultSetMetadata getResultSetMetadata(LensSessionHandle sessionHandle, QueryHandle queryHandle)
     throws LensException {
     try {
-      log.info("GetResultSetMetadata: session:{} query: {}", sessionHandle,  queryHandle);
+      log.info("GetResultSetMetadata: session:{} query: {}", sessionHandle, queryHandle);
       acquire(sessionHandle);
       LensResultSet resultSet = getResultset(queryHandle);
       if (resultSet != null) {
@@ -2267,7 +2260,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       acquire(sessionHandle);
       Configuration qconf = getLensConf(sessionHandle, lensConf);
       ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query, getSession(sessionHandle)
-          .getLoggedInUser(), lensConf, qconf, drivers.values());
+        .getLoggedInUser(), lensConf, qconf, drivers.values());
       explainQueryContext.setLensSessionIdentifier(sessionHandle.getPublicId().toString());
       accept(query, qconf, SubmitOp.EXPLAIN);
       rewriteAndSelect(explainQueryContext);
@@ -2383,6 +2376,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           break;
         case LAUNCHED:
         case RUNNING:
+        case EXECUTED:
           try {
             launchedQueries.add(ctx);
           } catch (final Exception e) {
@@ -2486,69 +2480,54 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     }
 
     return isHealthy
-        ? new HealthStatus(isHealthy, "QueryExecution service is healthy.")
-        : new HealthStatus(isHealthy, details.toString());
+      ? new HealthStatus(isHealthy, "QueryExecution service is healthy.")
+      : new HealthStatus(isHealthy, details.toString());
   }
-
   /*
    * (non-Javadoc)
    *
    * @see org.apache.lens.server.api.query.QueryExecutionService#getHttpResultSet(org.apache.lens.api.LensSessionHandle,
    * org.apache.lens.api.query.QueryHandle)
    */
+
   @Override
   public Response getHttpResultSet(LensSessionHandle sessionHandle, QueryHandle queryHandle) throws LensException {
+    LensResultSet resultSet = getResultset(queryHandle);
+    if (!resultSet.isHttpResultAvailable()) {
+      throw new NotFoundException("http result not available");
+    }
+    final Path resultPath = new Path(resultSet.getOutputPath());
     final QueryContext ctx = getQueryContext(sessionHandle, queryHandle);
-    LensResultSet result = getResultset(queryHandle);
-    if (result instanceof LensPersistentResult) {
-      final Path resultPath = new Path(((PersistentResultSet) result).getOutputPath());
+    String resultFSReadUrl = conf.get(RESULT_FS_READ_URL);
+    if (resultFSReadUrl != null) {
       try {
-        FileSystem fs = resultPath.getFileSystem(conf);
-        if (fs.isDirectory(resultPath)) {
-          throw new NotFoundException("Http result not available for query:" + queryHandle.toString());
-        }
-      } catch (IOException e) {
-        log.warn("Unable to get status for Result Directory", e);
-        throw new NotFoundException("Http result not available for query:" + queryHandle.toString());
-      }
-      String resultFSReadUrl = ctx.getConf().get(RESULT_FS_READ_URL);
-      if (resultFSReadUrl != null) {
-        try {
-          URI resultReadPath = new URI(resultFSReadUrl + resultPath.toUri().getPath() + "?op=OPEN&user.name="
-            + getSession(sessionHandle).getClusterUser());
-          return Response.seeOther(resultReadPath)
-            .header("content-disposition", "attachment; filename = " + resultPath.getName())
-            .type(MediaType.APPLICATION_OCTET_STREAM).build();
-        } catch (URISyntaxException e) {
-          throw new LensException(e);
-        }
-      } else {
-        StreamingOutput stream = new StreamingOutput() {
-          @Override
-          public void write(OutputStream os) throws IOException {
-            FSDataInputStream fin = null;
-            try {
-              FileSystem fs = resultPath.getFileSystem(ctx.getConf());
-              fin = fs.open(resultPath);
-              UtilityMethods.pipe(fin, os);
-            } finally {
-              if (fin != null) {
-                fin.close();
-              }
-
-            }
-          }
-        };
-        return Response.ok(stream).header("content-disposition", "attachment; filename = " + resultPath.getName())
+        URI resultReadPath = new URI(resultFSReadUrl + resultPath.toUri().getPath() + "?op=OPEN&user.name="
+          + getSession(sessionHandle).getClusterUser());
+        return Response.seeOther(resultReadPath)
+          .header("content-disposition", "attachment; filename = " + resultPath.getName())
           .type(MediaType.APPLICATION_OCTET_STREAM).build();
+      } catch (URISyntaxException e) {
+        throw new LensException(e);
       }
     } else {
-      String entity = "";
-      if (result instanceof InMemoryResultSet || result instanceof PersistentResultSet) {
-        entity = "Result is available in driver's "
-          + (result instanceof InMemoryResultSet ? "memory" : "persistence") + ".";
-      }
-      return Response.status(Response.Status.NOT_FOUND).entity(entity).build();
+      StreamingOutput stream = new StreamingOutput() {
+        @Override
+        public void write(OutputStream os) throws IOException {
+          FSDataInputStream fin = null;
+          try {
+            FileSystem fs = resultPath.getFileSystem(ctx.getConf());
+            fin = fs.open(resultPath);
+            UtilityMethods.pipe(fin, os);
+          } finally {
+            if (fin != null) {
+              fin.close();
+            }
+
+          }
+        }
+      };
+      return Response.ok(stream).header("content-disposition", "attachment; filename = " + resultPath.getName())
+        .type(MediaType.APPLICATION_OCTET_STREAM).build();
     }
   }
 
@@ -2698,7 +2677,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     Collection<ResourceEntry> pendingResources =
       session.getPendingSessionResourcesForDatabase(ctx.getDatabase());
     log.info("Adding pending {} session resources for session {} for database {}", pendingResources.size(),
-      sessionIdentifier,  ctx.getDatabase());
+      sessionIdentifier, ctx.getDatabase());
     List<ResourceEntry> failedResources = addResources(pendingResources, sessionHandle, hiveDriver);
     // Mark added resources so that we don't add them again. If any of the resources failed
     // to be added, then they will be added again
@@ -2761,7 +2740,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     }
 
     log.debug("launchedQueries.remove(finishedQuery) has returned [{}] for finished query with query id:[{}]", modified,
-        finishedQuery.getQueryHandleString());
+      finishedQuery.getQueryHandleString());
     return modified;
   }
 
@@ -2801,7 +2780,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   private void processWaitingQueries(final FinishedLensQuery finishedQuery) {
 
     Set<QueryContext> eligibleWaitingQueries = this.waitingQueriesSelector
-        .selectQueries(finishedQuery, this.waitingQueries);
+      .selectQueries(finishedQuery, this.waitingQueries);
 
     if (eligibleWaitingQueries.isEmpty()) {
       log.debug("No queries eligible to move out of waiting state.");

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionStatisticsGenerator.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionStatisticsGenerator.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionStatisticsGenerator.java
index b57bc64..55cabe2 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionStatisticsGenerator.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionStatisticsGenerator.java
@@ -39,20 +39,15 @@ public class QueryExecutionStatisticsGenerator extends AsyncEventListener<QueryE
   /** The Constant LOG. */
   private static final Logger LOG = LoggerFactory.getLogger(QueryExecutionStatisticsGenerator.class);
 
-  /** The query service. */
-  private final QueryExecutionServiceImpl queryService;
-
   /** The event service. */
   private final LensEventService eventService;
 
   /**
    * Instantiates a new query execution statistics generator.
    *
-   * @param queryService the query service
    * @param eventService the event service
    */
-  public QueryExecutionStatisticsGenerator(QueryExecutionServiceImpl queryService, LensEventService eventService) {
-    this.queryService = queryService;
+  public QueryExecutionStatisticsGenerator(LensEventService eventService) {
     this.eventService = eventService;
   }
 
@@ -68,7 +63,7 @@ public class QueryExecutionStatisticsGenerator extends AsyncEventListener<QueryE
     }
     QueryHandle handle = ended.getQueryHandle();
     QueryExecutionStatistics event = new QueryExecutionStatistics(System.currentTimeMillis());
-    QueryContext ctx = queryService.getQueryContext(handle);
+    QueryContext ctx = ended.getQueryContext();
     if (ctx == null) {
       LOG.warn("Could not find the context for " + handle + " for event:" + ended.getCurrentValue()
         + ". No stat generated");
@@ -88,7 +83,7 @@ public class QueryExecutionStatisticsGenerator extends AsyncEventListener<QueryE
     QueryDriverStatistics driverStats = new QueryDriverStatistics();
     driverStats.setDriverQuery(ctx.getSelectedDriverQuery());
     driverStats.setStartTime(ctx.getDriverStatus().getDriverStartTime());
-    driverStats.setEndTime(ctx.getDriverStatus().getDriverStartTime());
+    driverStats.setEndTime(ctx.getDriverStatus().getDriverFinishTime());
     event.setDriverStats(driverStats);
     try {
       if (LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/java/org/apache/lens/server/query/ResultFormatter.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/ResultFormatter.java b/lens-server/src/main/java/org/apache/lens/server/query/ResultFormatter.java
index af42eb0..f568b17 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/ResultFormatter.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/ResultFormatter.java
@@ -65,17 +65,16 @@ public class ResultFormatter extends AsyncEventListener<QueryExecuted> {
    */
   @Override
   public void process(QueryExecuted event) {
-    formatOutput(event);
+    formatOutput(queryService.getQueryContext(event.getQueryHandle()));
   }
 
   /**
    * Format output.
    *
-   * @param event the event
+   * @param ctx the query context
    */
-  private void formatOutput(QueryExecuted event) {
-    QueryHandle queryHandle = event.getQueryHandle();
-    QueryContext ctx = queryService.getQueryContext(queryHandle);
+  private void formatOutput(QueryContext ctx) {
+    QueryHandle queryHandle = ctx.getQueryHandle();
     this.logSegregationContext.setLogSegragationAndQueryId(ctx.getQueryHandleString());
     try {
       if (!ctx.isPersistent()) {
@@ -86,9 +85,8 @@ public class ResultFormatter extends AsyncEventListener<QueryExecuted> {
         log.info("Result formatter for {}", queryHandle);
         LensResultSet resultSet = queryService.getDriverResultset(queryHandle);
         boolean isPersistedInDriver = resultSet instanceof PersistentResultSet;
-        if (isPersistedInDriver) {
-          // skip result formatting if persisted size is huge
-          Path persistedDirectory = new Path(ctx.getHdfsoutPath());
+        if (isPersistedInDriver) {          // skip result formatting if persisted size is huge
+          Path persistedDirectory = new Path(ctx.getDriverResultPath());
           FileSystem fs = persistedDirectory.getFileSystem(ctx.getConf());
           long size = fs.getContentSummary(persistedDirectory).getLength();
           long threshold = ctx.getConf().getLong(LensConfConstants.RESULT_FORMAT_SIZE_THRESHOLD,
@@ -112,7 +110,7 @@ public class ResultFormatter extends AsyncEventListener<QueryExecuted> {
           }
           if (isPersistedInDriver) {
             log.info("Result formatter for {} in persistent result", queryHandle);
-            Path persistedDirectory = new Path(ctx.getHdfsoutPath());
+            Path persistedDirectory = new Path(ctx.getDriverResultPath());
             // write all files from persistent directory
             ((PersistedOutputFormatter) formatter).addRowsFromPersistedPath(persistedDirectory);
           } else {
@@ -121,6 +119,7 @@ public class ResultFormatter extends AsyncEventListener<QueryExecuted> {
             while (inmemory.hasNext()) {
               ((InMemoryOutputFormatter) formatter).writeRow(inmemory.next());
             }
+            inmemory.setFullyAccessed(true);
           }
           if (ctx.getConf().getBoolean(LensConfConstants.QUERY_OUTPUT_WRITE_FOOTER,
             LensConfConstants.DEFAULT_OUTPUT_WRITE_FOOTER)) {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/main/resources/lensserver-default.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/main/resources/lensserver-default.xml b/lens-server/src/main/resources/lensserver-default.xml
index 3c8fc09..1e6bd10 100644
--- a/lens-server/src/main/resources/lensserver-default.xml
+++ b/lens-server/src/main/resources/lensserver-default.xml
@@ -279,9 +279,9 @@
 
   <!-- Finished Query Purging Configurations -->
   <property>
-    <name>lens.server.max.finished.queries</name>
-    <value>100</value>
-    <description>Maximum number of finished queries which lens server will keep in memory before purging.</description>
+    <name>lens.server.querypurger.sleep.interval</name>
+    <value>10000</value>
+    <description>The interval(milliseconds) with which purger to run periodically. Default 10 sec. </description>
   </property>
   <property>
     <name>lens.server.domain</name>

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/LensJerseyTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/LensJerseyTest.java b/lens-server/src/test/java/org/apache/lens/server/LensJerseyTest.java
index 05bd99f..3dad050 100644
--- a/lens-server/src/test/java/org/apache/lens/server/LensJerseyTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/LensJerseyTest.java
@@ -23,15 +23,17 @@ import static org.testng.Assert.*;
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.URI;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
 
 import javax.ws.rs.core.UriBuilder;
 
 import org.apache.lens.driver.hive.TestRemoteHiveDriver;
-import org.apache.lens.server.api.LensConfConstants;
 import org.apache.lens.server.api.metrics.LensMetricsUtil;
 import org.apache.lens.server.api.metrics.MetricsService;
 import org.apache.lens.server.model.LogSegregationContext;
 import org.apache.lens.server.model.MappedDiagnosticLogSegregationContext;
+import org.apache.lens.server.query.QueryExecutionServiceImpl;
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hive.service.Service;
@@ -41,6 +43,7 @@ import org.glassfish.jersey.test.JerseyTest;
 import org.testng.annotations.AfterSuite;
 import org.testng.annotations.BeforeSuite;
 
+import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 
 /**
@@ -186,7 +189,6 @@ public abstract class LensJerseyTest extends JerseyTest {
    */
   public void restartLensServer() {
     HiveConf h = getServerConf();
-    h.set(LensConfConstants.MAX_NUMBER_OF_FINISHED_QUERY, "0");
     restartLensServer(h);
   }
 
@@ -204,4 +206,19 @@ public abstract class LensJerseyTest extends JerseyTest {
     LensServices.get().start();
     System.out.println("Lens services restarted!");
   }
+  public static void waitForPurge(int allowUnpurgable,
+    ConcurrentLinkedQueue<QueryExecutionServiceImpl.FinishedQuery> finishedQueries) throws InterruptedException {
+    List<QueryExecutionServiceImpl.FinishedQuery> unPurgable = Lists.newArrayList();
+    for (QueryExecutionServiceImpl.FinishedQuery finishedQuery : finishedQueries) {
+      if (!finishedQuery.canBePurged()) {
+        unPurgable.add(finishedQuery);
+      }
+    }
+    if (unPurgable.size() > allowUnpurgable) {
+      throw new RuntimeException("finished queries can't be purged: " + unPurgable);
+    }
+    while (finishedQueries.size() > allowUnpurgable) {
+      Thread.sleep(5000);
+    }
+  }
 }


[31/50] [abbrv] lens git commit: LENS-629 : A new improved web client for Lens

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/QueryDetailResultComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryDetailResultComponent.js b/lens-ui/app/components/QueryDetailResultComponent.js
new file mode 100644
index 0000000..b969a4a
--- /dev/null
+++ b/lens-ui/app/components/QueryDetailResultComponent.js
@@ -0,0 +1,192 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import Loader from '../components/LoaderComponent';
+import AdhocQueryStore from '../stores/AdhocQueryStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import UserStore from '../stores/UserStore';
+import QueryPreview from './QueryPreviewComponent';
+
+let interval = null;
+
+function isResultAvailableOnServer (handle) {
+
+  // always check before polling
+  let query = AdhocQueryStore.getQueries()[handle];
+  if (query && query.status && query.status.status === 'SUCCESSFUL') {
+    return true;
+  }
+  return false;
+}
+
+function fetchResult (secretToken, handle) {
+
+  // this condition checks the query object, else
+  // we fetch it with the handle that we have
+  if (isResultAvailableOnServer(handle)) {
+    let query = AdhocQueryStore.getQueries()[handle];
+    let mode = query.isPersistent ? 'PERSISTENT' : 'INMEMORY';
+    AdhocQueryActions.getQueryResult(secretToken, handle, mode);
+  } else {
+    AdhocQueryActions.getQuery(secretToken, handle);
+  }
+}
+
+function constructTable (tableData) {
+  if (!tableData.columns && !tableData.results) return;
+  let header = tableData.columns.map(column => {
+    return <th>{ column.name }</th>;
+  });
+  let rows = tableData.results
+    .map(row => {
+      return (<tr>{row.values.values.map(cell => {
+        return <td>{(cell && cell.value) || <span style={{color: 'red'}}>NULL</span>}</td>;
+      })}</tr>);
+  });
+
+  // in case the results are empty, happens when LENS server has restarted
+  // all in-memory results are wiped clean
+  if (!rows.length) {
+    let colWidth = tableData.columns.length;
+    rows = <tr>
+        <td colSpan={colWidth} style={{color: 'red', textAlign: 'center'}}>
+          Result set no longer available with server.</td>
+      </tr>;
+  }
+
+  return (
+    <div class="table-responsive">
+      <table className="table table-striped table-condensed">
+        <thead>
+          <tr>{header}</tr>
+        </thead>
+        <tbody>{rows}</tbody>
+      </table>
+    </div>
+  );
+}
+
+class QueryDetailResult extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = { loading: true, queryResult: {}, query: null };
+    this._onChange = this._onChange.bind(this);
+    this.pollForResult = this.pollForResult.bind(this);
+  }
+
+  componentDidMount () {
+    let secretToken = UserStore.getUserDetails().secretToken;
+    this.pollForResult(secretToken, this.props.params.handle);
+
+    AdhocQueryStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    clearInterval(interval);
+    AdhocQueryStore.removeChangeListener(this._onChange);
+  }
+
+  componentWillReceiveProps (props) {
+    this.state = { loading: true, queryResult: {}, query: null };
+    let secretToken = UserStore.getUserDetails().secretToken;
+    clearInterval(interval);
+    this.pollForResult(secretToken, props.params.handle);
+  }
+
+  render () {
+    let query = this.state.query;
+    let queryResult = this.state.queryResult;
+    let result = '';
+
+    // check if the query was persistent or in-memory
+    if (query && query.isPersistent && query.status.status === 'SUCCESSFUL') {
+      result = (<div className="text-center">
+        <a href={queryResult.downloadURL} download>
+          <span className="glyphicon glyphicon-download-alt	"></span> Click
+          here to download the results as a CSV file
+        </a>
+      </div>);
+    } else {
+      result = constructTable(this.state.queryResult);
+    }
+
+
+    if (this.state.loading) result = <Loader size="8px" margin="2px"></Loader>;
+
+    return (
+      <div className="panel panel-default">
+      <div className="panel-heading">
+        <h3 className="panel-title">Query Result</h3>
+      </div>
+      <div className="panel-body" style={{overflowY: 'auto', padding: '0px',
+        maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+        <div>
+          <QueryPreview key={query && query.queryHandle.handleId}
+            {...query} />
+        </div>
+        {result}
+      </div>
+    </div>
+    );
+  }
+
+  pollForResult (secretToken, handle) {
+
+    // fetch results immediately if present, don't wait for 5 seconds
+    // in setInterval below.
+    // FIXME if I put a return in if construct, setInterval won't execute which
+    // shouldn't but the backend API isn't stable enough, and if this call fails
+    // we'll not be able to show the results and it'll show a loader, thoughts?
+    fetchResult(secretToken, handle);
+
+    interval = setInterval(function () {
+      fetchResult(secretToken, handle);
+    }, 5000);
+  }
+
+  _onChange () {
+    let handle = this.props.params.handle;
+    let query = AdhocQueryStore.getQueries()[handle];
+    let result = AdhocQueryStore.getQueryResult(handle);
+    let loading = true;
+
+    let failed = query && query.status && query.status.status === 'FAILED';
+    let success = query && query.status && query.status.status === 'SUCCESSFUL';
+
+    if (failed || success && result) {
+      clearInterval(interval);
+      loading = false;
+    }
+
+    // check first if the query failed, clear the interval, and show it
+    // setState when query is successful AND we've the results OR it failed
+    let state = {
+      loading: loading,
+      queryResult: result || {}, // result can be undefined so guarding it
+      query: query
+    }
+
+    this.setState(state);
+
+  }
+}
+
+export default QueryDetailResult;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/QueryOperationsComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryOperationsComponent.js b/lens-ui/app/components/QueryOperationsComponent.js
new file mode 100644
index 0000000..a17a636
--- /dev/null
+++ b/lens-ui/app/components/QueryOperationsComponent.js
@@ -0,0 +1,87 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { Link } from 'react-router';
+import ClassNames from 'classnames';
+
+class QueryOperations extends React.Component {
+  constructor () {
+    super();
+    this.state = { isCollapsed: false };
+    this.toggle = this.toggle.bind(this);
+  }
+
+  toggle () {
+    this.setState({ isCollapsed: !this.state.isCollapsed });
+  }
+
+  render () {
+    let collapseClass = ClassNames({
+      'pull-right': true,
+      'glyphicon': true,
+      'glyphicon-chevron-up': !this.state.isCollapsed,
+      'glyphicon-chevron-down': this.state.isCollapsed
+    });
+
+    let panelBodyClassName = ClassNames({
+      'panel-body': true,
+      'hide': this.state.isCollapsed
+    });
+
+    return (
+      <div className="panel panel-default">
+        <div className="panel-heading">
+          <h3 className="panel-title">
+            Queries
+            <span className={collapseClass} onClick={this.toggle}></span>
+          </h3>
+        </div>
+        <div className={panelBodyClassName}>
+          <ul style={{listStyle: 'none', paddingLeft: '0px',
+            marginBottom: '0px'}}>
+            <li><Link to="results">All</Link></li>
+            <li>
+              <Link to="results" query={{category: 'running'}}>
+                Running
+              </Link>
+            </li>
+            <li>
+              <Link to="results" query={{category: 'successful'}}>
+                Completed
+              </Link>
+            </li>
+            <li>
+              <Link to="results" query={{category: 'queued'}}>
+                Queued
+              </Link>
+            </li>
+            <li>
+              <Link to="results" query={{category: 'failed'}}>
+                Failed
+              </Link>
+            </li>
+          </ul>
+        </div>
+      </div>
+    );
+  }
+}
+
+export default QueryOperations;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/QueryPreviewComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryPreviewComponent.js b/lens-ui/app/components/QueryPreviewComponent.js
new file mode 100644
index 0000000..fabe383
--- /dev/null
+++ b/lens-ui/app/components/QueryPreviewComponent.js
@@ -0,0 +1,176 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import Moment from 'moment';
+import { Link } from 'react-router';
+import CodeMirror from 'codemirror';
+import 'codemirror/mode/sql/sql.js';
+import 'codemirror/addon/runmode/runmode.js';
+
+import Loader from '../components/LoaderComponent';
+import UserStore from '../stores/UserStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+
+class QueryPreview extends React.Component {
+  constructor (props) {
+    super (props);
+    this.state = {showDetail: false};
+    this.toggleQueryDetails = this.toggleQueryDetails.bind(this);
+    this.cancelQuery = this.cancelQuery.bind(this);
+  }
+
+	render () {
+    let query = this.props;
+
+    if (!query.userQuery) return null;
+
+    // code below before the return prepares the data to render, turning out
+    // crude properties to glazed, garnished ones e.g. formatting of query
+    let codeTokens = [];
+
+    CodeMirror
+      .runMode(query.userQuery,
+        'text/x-mysql', function (text, style) {
+
+        // this method is called for every token and gives the
+        // token and style class for it.
+        codeTokens.push(<span className={'cm-' + style}>{text}</span>);
+
+      });
+
+    // figuring out the className for query status
+    // TODO optimize this construct
+    let statusTypes = {
+      'EXECUTED': 'success',
+      'SUCCESSFUL': 'success',
+      'FAILED': 'danger',
+      'CANCELED': 'danger',
+      'CLOSED': 'warning',
+      'QUEUED': 'info',
+      'RUNNING': 'info'
+    };
+
+    let statusClass = 'label-' + statusTypes[query.status.status] ||
+      'label-info';
+    let handle = query.queryHandle.handleId;
+    let executionTime = (query.finishTime - query.submissionTime)/(1000*60);
+    let statusType = query.status.status === 'ERROR'? 'Error: ' : 'Status: ';
+    let seeResult = '';
+    let statusMessage = query.status.status === 'SUCCESSFUL'?
+      query.status.statusMessage :
+      query.status.errorMessage;
+
+    if (query.status.status === 'SUCCESSFUL') {
+      seeResult = (<Link to="result" params={{handle: handle}}
+        className="btn btn-success btn-xs pull-right" style={{marginLeft: '5px'}}>
+        See Result
+      </Link>);
+    }
+
+
+    return (
+      <section>
+        <div className="panel panel-default">
+          <pre className="cm-s-default" style={{cursor: 'pointer',
+            border: '0px', marginBottom: '0px'}}
+            onClick={this.toggleQueryDetails}>
+
+            {codeTokens}
+
+            <label className={"pull-right label " + statusClass}>
+              {query.status.status}
+            </label>
+
+            {query.queryName && (
+              <label className="pull-right label label-primary"
+                style={{marginRight: '5px'}}>
+                {query.queryName}
+              </label>
+            )}
+
+          </pre>
+
+          {this.state.showDetail && (
+            <div className="panel-body" style={{borderTop: '1px solid #cccccc',
+            paddingBottom: '0px'}} key={'preview' + handle}>
+              <div className="row">
+                <div className="col-lg-4 col-sm-4">
+                  <span className="text-muted">Name </span>
+                  <strong>{ query.queryName || 'Not specified'}</strong>
+                </div>
+                <div className="col-lg-4 col-sm-4">
+                  <span className="text-muted">Submitted </span>
+                  <strong>
+                    { Moment(query.submissionTime).format('Do MMM YY, hh:mm:ss a')}
+                  </strong>
+                </div>
+                <div className="col-lg-4 col-sm-4">
+                  <span className="text-muted">Execution time </span>
+                  <strong>
+
+                    { executionTime > 0 ?
+                        Math.ceil(executionTime) +
+                          (executionTime > 1 ? ' mins': ' min') :
+                        'Still running'
+                    }
+                  </strong>
+                </div>
+              </div>
+              <div className="row">
+                <div
+                  className={'alert alert-' + statusTypes[query.status.status]}
+                  style={{marginBottom: '0px', padding: '5px 15px 5px 15px'}}>
+                    <p>
+                      <strong>{statusType}</strong>
+                      {statusMessage || query.status.status}
+
+                      {seeResult}
+
+                      <Link to="query" query={{handle: query.queryHandle.handleId}}
+                        className="pull-right">
+                        Edit Query
+                      </Link>
+
+                    </p>
+                </div>
+              </div>
+            </div>
+          )}
+        </div>
+      </section>
+    );
+  }
+
+  toggleQueryDetails () {
+    this.setState({ showDetail: !this.state.showDetail });
+  }
+
+  cancelQuery () {
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let handle = this.props && this.props.queryHandle &&
+      this.props.queryHandle.handleId;
+
+    if (!handle)  return;
+
+    AdhocQueryActions.cancelQuery(secretToken, handle);
+  }
+}
+
+export default QueryPreview;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/QueryResultsComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryResultsComponent.js b/lens-ui/app/components/QueryResultsComponent.js
new file mode 100644
index 0000000..6e4b8c2
--- /dev/null
+++ b/lens-ui/app/components/QueryResultsComponent.js
@@ -0,0 +1,123 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import Loader from '../components/LoaderComponent';
+import AdhocQueryStore from '../stores/AdhocQueryStore';
+import UserStore from '../stores/UserStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import QueryPreview from './QueryPreviewComponent';
+
+// this method fetches the results based on props.query.category
+function getResults (props) {
+  let email = UserStore.getUserDetails().email;
+  let secretToken = UserStore.getUserDetails().secretToken;
+
+  if (props.query.category) {
+
+    // fetch either running or completed results
+    AdhocQueryActions
+      .getQueries(secretToken, email, { state: props.query.category });
+  } else {
+
+    // fetch all
+    AdhocQueryActions.getQueries(secretToken, email);
+  }
+}
+
+function getQueries () {
+  return AdhocQueryStore.getQueries();
+}
+
+class QueryResults extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = { queries: {}, queriesReceived: false };
+    this._onChange = this._onChange.bind(this);
+
+    getResults(props);
+  }
+
+  componentDidMount () {
+    AdhocQueryStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    AdhocQueryStore.removeChangeListener(this._onChange);
+  }
+
+  componentWillReceiveProps (props) {
+    getResults(props);
+    this.setState({queries: {}, queriesReceived: false});
+  }
+
+  render () {
+    let queries = '';
+
+    let queryMap = this.state.queries;
+    queries = Object.keys(queryMap)
+      .sort(function (a, b) {
+        return queryMap[b].submissionTime - queryMap[a].submissionTime;
+      })
+      .map((queryHandle) => {
+      let query = queryMap[queryHandle];
+
+      return (
+        <QueryPreview key={query.queryHandle.handleId} {...query} />
+      );
+    }); // end of map
+
+    // FIXME find a better way to do it.
+    // show a loader when queries are empty, or no queries.
+    // this is managed by seeing the length of queries and
+    // a state variable 'queriesReceived'.
+    // if queriesReceived is true and the length is 0, show no queries else
+    // show a loader
+    let queriesLength = Object.keys(this.state.queries).length;
+
+    if (!queriesLength && !this.state.queriesReceived) {
+      queries = <Loader size="8px" margin="2px" />;
+    } else if (!queriesLength && this.state.queriesReceived) {
+      queries = <div className="alert alert-danger">
+        <strong>Sorry</strong>, there were no queries to be shown.
+      </div>;
+    }
+
+    return (
+      <section>
+        <div style={{border: '1px solid #dddddd', borderRadius: '4px',
+          padding: '0px 8px 8px 8px'}}>
+          <h3 style={{margin: '8px 10px'}}>Results</h3>
+          <hr style={{marginTop: '6px' }}/>
+          <div style={{overflowY: 'auto',
+            maxHeight: this.props.toggleQueryBox ? '300px': '600px'}}>
+            {queries}
+          </div>
+        </div>
+      </section>
+    );
+  }
+
+  _onChange () {
+    this.setState({ queries: getQueries(), queriesReceived: true});
+  }
+}
+
+export default QueryResults;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/RequireAuthenticationComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/RequireAuthenticationComponent.js b/lens-ui/app/components/RequireAuthenticationComponent.js
new file mode 100644
index 0000000..9a755b0
--- /dev/null
+++ b/lens-ui/app/components/RequireAuthenticationComponent.js
@@ -0,0 +1,37 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import UserStore from '../stores/UserStore';
+
+let RequireAuthentication = (Component) => {
+  return class Authenticated extends React.Component {
+    static willTransitionTo (transition) {
+      if (!UserStore.isUserLoggedIn()) {
+        transition.redirect('/login', {}, {'nextPath': transition.path});
+      }
+    }
+
+    render () {
+      return <Component {...this.props} />
+    }
+  }
+};
+
+export default RequireAuthentication;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/SidebarComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/SidebarComponent.js b/lens-ui/app/components/SidebarComponent.js
new file mode 100644
index 0000000..dcc8737
--- /dev/null
+++ b/lens-ui/app/components/SidebarComponent.js
@@ -0,0 +1,38 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import CubeTree from './CubeTreeComponent';
+import Database from './DatabaseComponent';
+import QueryOperations from './QueryOperationsComponent';
+
+class Sidebar extends React.Component {
+  render() {
+    return (
+      <section>
+        <QueryOperations />
+        <CubeTree />
+        <Database />
+      </section>
+    );
+  }
+};
+
+export default Sidebar;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/TableSchemaComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/TableSchemaComponent.js b/lens-ui/app/components/TableSchemaComponent.js
new file mode 100644
index 0000000..67dc25a
--- /dev/null
+++ b/lens-ui/app/components/TableSchemaComponent.js
@@ -0,0 +1,131 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import TableStore from '../stores/TableStore';
+import UserStore from '../stores/UserStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import Loader from '../components/LoaderComponent';
+
+function getTable (tableName, database) {
+  let tables = TableStore.getTables(database);
+  return tables && tables[tableName];
+}
+
+class TableSchema extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {table: {}};
+    this._onChange = this._onChange.bind(this);
+
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let tableName = props.params.tableName;
+    let database = props.query.database;
+    AdhocQueryActions.getTableDetails(secretToken, tableName, database);
+  }
+
+  componentDidMount () {
+    TableStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    TableStore.removeChangeListener(this._onChange);
+  }
+
+  componentWillReceiveProps (props) {
+    let tableName = props.params.tableName;
+    let database = props.query.database;
+    if (!TableStore.getTables(database)[tableName].isLoaded) {
+      let secretToken = UserStore.getUserDetails().secretToken;
+
+      AdhocQueryActions
+        .getTableDetails(secretToken, tableName, database);
+
+      // set empty state as we do not have the loaded data.
+      this.setState({table: {}});
+      return;
+    }
+
+    this.setState({
+      table: TableStore.getTables(database)[tableName]
+    });
+  }
+
+  render () {
+    let schemaSection = null;
+
+
+    if (this.state.table && !this.state.table.isLoaded) {
+      schemaSection = <Loader size="8px" margin="2px" />;
+    } else {
+      schemaSection = (<div className="row">
+          <div className="table-responsive">
+            <table className="table table-striped">
+              <thead>
+              <caption className="bg-primary text-center">Columns</caption>
+                <tr><th>Name</th><th>Type</th><th>Description</th></tr>
+              </thead>
+              <tbody>
+                {this.state.table &&
+                  this.state.table.columns.map(col => {
+                    return (
+                      <tr key={this.state.table.name + '|' + col.name}>
+                        <td>{col.name}</td>
+                        <td>{col.type}</td>
+                        <td>{col.comment || 'No description available'}</td>
+                      </tr>
+                    )
+                })}
+              </tbody>
+            </table>
+          </div>
+        </div>);
+    }
+
+    return (
+      <section>
+        <div className="panel panel-default">
+          <div className="panel-heading">
+            <h3 className="panel-title">Schema Details: &nbsp;
+              <strong className="text-primary">
+                 {this.props.query.database}.{this.props.params.tableName}
+              </strong>
+            </h3>
+          </div>
+          <div className="panel-body" style={{overflowY: 'auto',
+            maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+            {schemaSection}
+          </div>
+        </div>
+
+      </section>
+
+    );
+  }
+
+  _onChange () {
+    this.setState({
+      table: getTable(this.props.params.tableName,
+        this.props.query.database)
+    });
+  }
+}
+
+export default TableSchema;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/TableTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/TableTreeComponent.js b/lens-ui/app/components/TableTreeComponent.js
new file mode 100644
index 0000000..026e443
--- /dev/null
+++ b/lens-ui/app/components/TableTreeComponent.js
@@ -0,0 +1,238 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import TreeView from 'react-treeview';
+import { Link } from 'react-router';
+import 'react-treeview/react-treeview.css';
+import ClassNames from 'classnames';
+
+import TableStore from '../stores/TableStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import UserStore from '../stores/UserStore';
+import Loader from '../components/LoaderComponent';
+import '../styles/css/tree.css';
+
+let filterString = '';
+
+function getState (page, filterString, database) {
+  let state = getTables(page, filterString, database);
+  state.page = page;
+  state.loading = false;
+  return state;
+}
+
+function getTables (page, filterString, database) {
+
+  // get all the tables
+  let tables = TableStore.getTables(database);
+  let pageSize = 10;
+  let allTables;
+  let startIndex;
+  let relevantIndexes;
+  let pageTables;
+
+  if (!filterString) {
+
+    // no need for filtering
+    allTables = Object.keys(tables);
+  } else {
+
+    // filter
+    allTables = Object.keys(tables).map(name => {
+      if (name.match(filterString)) return name;
+    }).filter(name => { return !!name; });
+  }
+
+  startIndex = (page - 1) * pageSize;
+  relevantIndexes = allTables.slice(startIndex, startIndex + pageSize);
+  pageTables = relevantIndexes.map(name => {
+    return tables[name];
+  });
+
+  return {
+    totalPages: Math.ceil(allTables.length/pageSize),
+    tables: pageTables
+  };
+}
+
+class TableTree extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {
+      tables: [],
+      totalPages: 0,
+      page: 0,
+      loading: true,
+      isCollapsed: false
+    };
+    this._onChange = this._onChange.bind(this);
+    this.prevPage = this.prevPage.bind(this);
+    this.nextPage = this.nextPage.bind(this);
+    this.toggle = this.toggle.bind(this);
+    this.validateClickEvent = this.validateClickEvent.bind(this);
+
+    if (!TableStore.getTables(props.database)) {
+      AdhocQueryActions
+        .getTables(UserStore.getUserDetails().secretToken, props.database);
+    } else {
+      let state = getState(1, '', props.database);
+      this.state = state;
+
+      // on page refresh only a single table is fetched, and hence we need to
+      // fetch others too.
+      if (!TableStore.areTablesCompletelyFetched(props.database)) {
+        AdhocQueryActions
+          .getTables(UserStore.getUserDetails().secretToken, props.database);
+      }
+    }
+  }
+
+  componentDidMount () {
+    TableStore.addChangeListener(this._onChange);
+
+    // listen for opening tree
+    this.refs.tableTree.getDOMNode()
+      .addEventListener('click', this.validateClickEvent);
+  }
+
+  componentWillUnmount () {
+    this.refs.tableTree.getDOMNode()
+      .removeEventListener('click', this.validateClickEvent);
+    TableStore.removeChangeListener(this._onChange);
+  }
+
+  render () {
+    let tableTree = '';
+
+    // construct tree
+    tableTree = this.state.tables.map(table => {
+      let label = (<Link to="tableschema" params={{tableName: table.name}}
+        title={table.name} query={{database: this.props.database}}>
+          {table.name}</Link>);
+      return (
+        <TreeView key={table.name} nodeLabel={label}
+          defaultCollapsed={true}>
+
+          {table.isLoaded ? table.columns.map(col => {
+            return (
+              <div className="treeNode" key={name + '|' + col.name}>
+                {col.name} ({col.type})
+              </div>
+            );
+          }) : <Loader size="4px" margin="2px" />}
+
+        </TreeView>
+      );
+    });
+
+    // show a loader when tree is loading
+    if (this.state.loading) {
+      tableTree = <Loader size="4px" margin="2px" />;
+    } else if (!this.state.tables.length) {
+      tableTree = (<div className="alert-danger" style={{padding: '8px 5px'}}>
+          <strong>Sorry, we couldn&#39;t find any tables.</strong>
+        </div>);
+    }
+
+    let pagination = this.state.tables.length ?
+      (
+        <div>
+          <div className="text-center">
+            <button className="btn btn-link glyphicon glyphicon-triangle-left page-back"
+              onClick={this.prevPage}>
+            </button>
+            <span>{this.state.page} of {this.state.totalPages}</span>
+            <button className="btn btn-link glyphicon glyphicon-triangle-right page-next"
+              onClick={this.nextPage}>
+            </button>
+          </div>
+        </div>
+      ) :
+      null;
+
+    return (
+      <div>
+        { !this.state.loading &&
+          <div className="form-group">
+            <input type="search" className="form-control"
+              placeholder="Type to filter tables"
+              onChange={this._filter.bind(this)}/>
+          </div>
+        }
+
+        {pagination}
+
+        <div ref="tableTree" style={{maxHeight: '350px', overflowY: 'auto'}}>
+          {tableTree}
+        </div>
+      </div>
+    );
+  }
+
+  _onChange (page) {
+
+    // so that page doesn't reset to beginning
+    page = page || this.state.page || 1;
+    this.setState(getState(page, filterString, this.props.database));
+  }
+
+  getDetails (tableName, database) {
+
+    // find the table
+    let table = this.state.tables.filter(table => {
+      return tableName === table.name;
+    });
+
+    if (table.length && table[0].isLoaded) return;
+
+    AdhocQueryActions
+      .getTableDetails(UserStore.getUserDetails().secretToken, tableName,
+        database);
+  }
+
+  _filter (event) {
+    filterString = event.target.value;
+    this._onChange();
+  }
+
+  prevPage () {
+    if (this.state.page - 1) this._onChange(this.state.page - 1);
+  }
+
+  nextPage () {
+    if (this.state.page < this.state.totalPages) {
+      this._onChange(this.state.page + 1);
+    }
+  }
+
+  toggle () {
+    this.setState({ isCollapsed: !this.state.isCollapsed });
+  }
+
+  validateClickEvent (e) {
+    if (e.target && e.target.nodeName === 'DIV' &&
+      e.target.nextElementSibling.nodeName === 'A') {
+      this.getDetails(e.target.nextElementSibling.textContent, this.props.database);
+    }
+  }
+
+}
+
+export default TableTree;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/constants/AdhocQueryConstants.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/constants/AdhocQueryConstants.js b/lens-ui/app/constants/AdhocQueryConstants.js
new file mode 100644
index 0000000..3c4f93a
--- /dev/null
+++ b/lens-ui/app/constants/AdhocQueryConstants.js
@@ -0,0 +1,51 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import KeyMirror from 'keyMirror';
+
+const AdhocQueryConstants = KeyMirror({
+  RECEIVE_CUBES: null,
+  RECEIVE_CUBES_FAILED: null,
+
+  RECEIVE_QUERY_HANDLE: null,
+  RECEIVE_QUERY_HANDLE_FAILED: null,
+
+  RECEIVE_CUBE_DETAILS: null,
+  RECEIVE_CUBE_DETAILS_FAILED: null,
+
+  RECEIVE_QUERIES: null,
+  RECEIVE_QUERIES_FAILED: null,
+
+  RECEIVE_QUERY_RESULT: null,
+  RECEIVE_QUERY_RESULT_FAILED: null,
+
+  RECEIVE_TABLES: null,
+  RECEIVE_TABLES_FAILED: null,
+
+  RECEIVE_TABLE_DETAILS: null,
+  RECEIVE_TABLE_DETAILS_FAILED: null,
+
+  RECEIVE_QUERY: null,
+  RECEIVE_QUERY_FAILED: null,
+
+  RECEIVE_DATABASES: null,
+  RECEIVE_DATABASES_FAILED: null
+});
+
+export default AdhocQueryConstants;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/constants/AppConstants.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/constants/AppConstants.js b/lens-ui/app/constants/AppConstants.js
new file mode 100644
index 0000000..48cd93e
--- /dev/null
+++ b/lens-ui/app/constants/AppConstants.js
@@ -0,0 +1,27 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import KeyMirror from 'keyMirror';
+
+const AppConstants = KeyMirror({
+  AUTHENTICATION_SUCCESS: null,
+  AUTHENTICATION_FAILED: null
+});
+
+export default AppConstants;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/dispatcher/AppDispatcher.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/dispatcher/AppDispatcher.js b/lens-ui/app/dispatcher/AppDispatcher.js
new file mode 100644
index 0000000..31b267c
--- /dev/null
+++ b/lens-ui/app/dispatcher/AppDispatcher.js
@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2014-2015, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+import { Dispatcher } from 'flux';
+
+const AppDispatcher = new Dispatcher();
+
+export default AppDispatcher;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/stores/AdhocQueryStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/AdhocQueryStore.js b/lens-ui/app/stores/AdhocQueryStore.js
new file mode 100644
index 0000000..7420270
--- /dev/null
+++ b/lens-ui/app/stores/AdhocQueryStore.js
@@ -0,0 +1,138 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import Config from 'config.json';
+
+var CHANGE_EVENT = 'change';
+var adhocDetails = {
+
+  queryHandle: null,
+  queries: {},
+  queryResults: {}, // map with handle being the key
+  dbName: Config.dbName
+};
+
+// TODO remove this.
+function receiveQueryHandle (payload) {
+  let id = payload.queryHandle.getElementsByTagName('handleId')[0].textContent;
+  adhocDetails.queryHandle = id;
+}
+
+function receiveQueries (payload) {
+  let queries = payload.queries;
+  let queryObjects = {};
+
+  queries.forEach((query) => {
+    queryObjects[query.queryHandle.handleId] = query;
+  });
+
+  adhocDetails.queries = queryObjects;
+}
+
+function receiveQuery (payload) {
+  let query = payload.query;
+  adhocDetails.queries[query.queryHandle.handleId] = query;
+}
+
+function receiveQueryResult (payload) {
+  let queryResult = {};
+  queryResult.type = payload && payload.type;
+
+  if (queryResult.type === 'INMEMORY') {
+    let resultRows = payload.queryResult && payload.queryResult.rows &&
+      payload.queryResult.rows.rows || [];
+    let columns = payload.columns && payload.columns.columns &&
+      payload.columns.columns.columns;
+
+    adhocDetails.queryResults[payload.handle] = {};
+    adhocDetails.queryResults[payload.handle].results = resultRows;
+    adhocDetails.queryResults[payload.handle].columns = columns;
+  } else {
+
+    // persistent
+    adhocDetails.queryResults[payload.handle] = {};
+    adhocDetails.queryResults[payload.handle].downloadURL = payload.downloadURL;
+  }
+}
+
+let AdhocQueryStore = assign({}, EventEmitter.prototype, {
+  getQueries () {
+    return adhocDetails.queries;
+  },
+
+  getQueryResult (handle) {
+    return adhocDetails.queryResults[handle];
+  },
+
+  // always returns the last-run-query's handle
+  getQueryHandle () {
+    return adhocDetails.queryHandle;
+  },
+
+  clearQueryHandle () {
+    adhocDetails.queryHandle = null;
+  },
+
+  getDbName () {
+    return adhocDetails.dbName
+  },
+
+  emitChange () {
+    this.emit(CHANGE_EVENT);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+AppDispatcher.register((action) => {
+  switch(action.actionType) {
+
+    case AdhocQueryConstants.RECEIVE_QUERY_HANDLE:
+      receiveQueryHandle(action.payload);
+      AdhocQueryStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_QUERIES:
+      receiveQueries(action.payload);
+      AdhocQueryStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_QUERY_RESULT:
+      receiveQueryResult(action.payload);
+      AdhocQueryStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_QUERY:
+      receiveQuery(action.payload);
+      AdhocQueryStore.emitChange();
+  }
+});
+
+export default AdhocQueryStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/stores/CubeStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/CubeStore.js b/lens-ui/app/stores/CubeStore.js
new file mode 100644
index 0000000..8b20b95
--- /dev/null
+++ b/lens-ui/app/stores/CubeStore.js
@@ -0,0 +1,84 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+// private methods
+function receiveCubes (payload) {
+  payload.cubes.elements && payload.cubes.elements.forEach(cube => {
+    if (!cubes[cube]) {
+      cubes[cube] = { name: cube, isLoaded: false };
+    }
+  });
+}
+
+function receiveCubeDetails (payload) {
+  let cubeDetails = payload.cubeDetails;
+
+  let dimensions = cubeDetails.dim_attributes &&
+    cubeDetails.dim_attributes.dim_attribute;
+  let measures = cubeDetails.measures &&
+    cubeDetails.measures.measure;
+
+  cubes[cubeDetails.name].measures = measures;
+  cubes[cubeDetails.name].dimensions = dimensions;
+  cubes[cubeDetails.name].isLoaded = true;
+}
+
+
+let CHANGE_EVENT = 'change';
+var cubes = {};
+
+let CubeStore = assign({}, EventEmitter.prototype, {
+  getCubes () {
+    return cubes;
+  },
+
+  emitChange () {
+    this.emit(CHANGE_EVENT);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+AppDispatcher.register((action) => {
+  switch(action.actionType) {
+    case AdhocQueryConstants.RECEIVE_CUBES:
+      receiveCubes(action.payload);
+      CubeStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_CUBE_DETAILS:
+      receiveCubeDetails(action.payload);
+      CubeStore.emitChange();
+      break;
+
+  }
+});
+
+export default CubeStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/stores/DatabaseStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/DatabaseStore.js b/lens-ui/app/stores/DatabaseStore.js
new file mode 100644
index 0000000..9f4490b
--- /dev/null
+++ b/lens-ui/app/stores/DatabaseStore.js
@@ -0,0 +1,62 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+function receiveDatabases (payload) {
+  databases = [];
+
+  databases = payload.databases.elements &&
+    payload.databases.elements.slice()
+}
+
+let CHANGE_EVENT = 'change';
+var databases = [];
+
+let DatabaseStore = assign({}, EventEmitter.prototype, {
+  getDatabases () {
+    return databases;
+  },
+
+  emitChange () {
+    this.emit(CHANGE_EVENT);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+AppDispatcher.register((action) => {
+  switch(action.actionType) {
+    case AdhocQueryConstants.RECEIVE_DATABASES:
+      receiveDatabases(action.payload);
+      DatabaseStore.emitChange();
+      break;
+  }
+});
+
+export default DatabaseStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/stores/TableStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/TableStore.js b/lens-ui/app/stores/TableStore.js
new file mode 100644
index 0000000..299d9e8
--- /dev/null
+++ b/lens-ui/app/stores/TableStore.js
@@ -0,0 +1,102 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+function receiveTables (payload) {
+  let database = payload.database;
+
+  if (!tables[database]) {
+    tables[database] = {};
+    tableCompleteness[database] = true;
+  }
+
+  payload.tables.elements &&
+    payload.tables.elements.forEach( table => {
+      if (!tables[database][table]) {
+        tables[database][table] = { name: table, isLoaded: false };
+      }
+    });
+}
+
+function receiveTableDetails (payload) {
+  if (payload.tableDetails) {
+    let database = payload.database;
+    let name = payload.tableDetails.name;
+    let table = assign({}, payload.tableDetails);
+    let columns = table.columns && table.columns.column || [];
+    table.columns = columns;
+
+    // check if tables contains the database and table entry,
+    // it won't be present when user directly arrived on this link.
+    if (!tables[database]) {
+      tables[database] = {};
+    }
+
+    if (!tables[database][name]) tables[database][name] = {};
+
+    tables[database][name] = table;
+    tables[database][name].isLoaded = true;
+  }
+}
+
+let CHANGE_EVENT = 'change';
+var tables = {};
+var tableCompleteness = {};
+
+let TableStore = assign({}, EventEmitter.prototype, {
+  getTables (database) {
+    return tables[database];
+  },
+
+  areTablesCompletelyFetched (database) {
+    return tableCompleteness[database];
+  },
+
+  emitChange () {
+    this.emit(CHANGE_EVENT);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+AppDispatcher.register((action) => {
+  switch(action.actionType) {
+    case AdhocQueryConstants.RECEIVE_TABLES:
+      receiveTables(action.payload);
+      TableStore.emitChange();
+      break;
+
+    case AdhocQueryConstants.RECEIVE_TABLE_DETAILS:
+      receiveTableDetails(action.payload);
+      TableStore.emitChange();
+      break;
+  }
+});
+
+export default TableStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/stores/UserStore.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/stores/UserStore.js b/lens-ui/app/stores/UserStore.js
new file mode 100644
index 0000000..47da021
--- /dev/null
+++ b/lens-ui/app/stores/UserStore.js
@@ -0,0 +1,132 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AppConstants from '../constants/AppConstants';
+import assign from 'object-assign';
+import { EventEmitter } from 'events';
+
+var CHANGE_EVENT = 'change';
+var userDetails = {
+  isUserLoggedIn: false,
+  email: '',
+  secretToken: '',
+  publicKey: ''
+};
+
+// keeping these methods out of the UserStore class as
+// components shouldn't lay their hands on them ;)
+function authenticateUser (details) {
+  userDetails = {
+    isUserLoggedIn: true,
+    email: details.email,
+    secretToken: new XMLSerializer().serializeToString(details.secretToken),
+    publicKey: details.secretToken.getElementsByTagName('publicId')[0]
+      .textContent
+  };
+
+  // store the details in localStorage if available
+
+  if (window.localStorage) {
+    let adhocCred = assign({}, userDetails, { timestamp: Date.now() });
+    window.localStorage.setItem('adhocCred', JSON.stringify(adhocCred));
+  }
+}
+
+function unauthenticateUser (details) {
+
+  // details contains error code and message
+  // which are not stored but passsed along
+  // during emitChange()
+  userDetails = {
+    isUserLoggedIn: false,
+    email: '',
+    secretToken: ''
+  };
+
+  // remove from localStorage as well
+  if (window.localStorage) localStorage.setItem('adhocCred', '');
+}
+
+// exposing only necessary methods for the components.
+var UserStore = assign({}, EventEmitter.prototype, {
+  isUserLoggedIn () {
+
+    if (userDetails && userDetails.isUserLoggedIn) {
+
+      return userDetails.isUserLoggedIn;
+    } else if (window.localStorage && localStorage.getItem('adhocCred')) {
+
+      // check in localstorage
+      let credentials = JSON.parse(localStorage.getItem('adhocCred'));
+
+      // check if it's valid or not
+      if (Date.now() - credentials.timestamp > 1800000) return false;
+
+      delete credentials.timestamp;
+      userDetails = assign({}, credentials);
+
+      return userDetails.isUserLoggedIn;
+    }
+
+    return false;
+  },
+
+  getUserDetails () {
+    return userDetails;
+  },
+
+  logout () {
+    unauthenticateUser();
+    this.emitChange();
+  },
+
+  emitChange (errorHash) {
+    this.emit(CHANGE_EVENT, errorHash);
+  },
+
+  addChangeListener (callback) {
+    this.on(CHANGE_EVENT, callback);
+  },
+
+  removeChangeListener (callback) {
+    this.removeListener(CHANGE_EVENT, callback);
+  }
+});
+
+// registering callbacks with the dispatcher. So verbose?? I know right!
+AppDispatcher.register((action) => {
+  switch(action.actionType) {
+    case AppConstants.AUTHENTICATION_SUCCESS:
+      authenticateUser(action.payload);
+      UserStore.emitChange();
+      break;
+
+    case AppConstants.AUTHENTICATION_FAILED:
+      unauthenticateUser(action.payload);
+
+      // action.payload => { responseCode, responseMessage }
+      UserStore.emitChange(action.payload);
+      break;
+  }
+});
+
+export default UserStore;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/styles/css/global.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/global.css b/lens-ui/app/styles/css/global.css
new file mode 100644
index 0000000..131ab46
--- /dev/null
+++ b/lens-ui/app/styles/css/global.css
@@ -0,0 +1,18 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/styles/css/login.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/login.css b/lens-ui/app/styles/css/login.css
new file mode 100644
index 0000000..b400cfb
--- /dev/null
+++ b/lens-ui/app/styles/css/login.css
@@ -0,0 +1,57 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+
+ /*For login form*/
+.form-signin {
+  max-width: 330px;
+  padding: 15px;
+  margin: 0 auto;
+}
+.form-signin .form-signin-heading,
+.form-signin .checkbox {
+  margin-bottom: 10px;
+}
+.form-signin .checkbox {
+  font-weight: normal;
+}
+.form-signin .form-control {
+  position: relative;
+  height: auto;
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+  padding: 10px;
+  font-size: 16px;
+}
+.form-signin .form-control:focus {
+  z-index: 2;
+}
+.form-signin input[type="email"] {
+  margin-bottom: -1px;
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.form-signin input[type="password"] {
+  margin-bottom: 10px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+/*login style ends*/

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/styles/css/query-component.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/query-component.css b/lens-ui/app/styles/css/query-component.css
new file mode 100644
index 0000000..a82165e
--- /dev/null
+++ b/lens-ui/app/styles/css/query-component.css
@@ -0,0 +1,34 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+
+ @media (max-width: 768px) {
+    .btn.responsive {
+        width:100%;
+        margin-bottom: 10px;
+    }
+}
+
+div.CodeMirror {
+  max-height: 150px;
+}
+
+li.CodeMirror-hint {
+  max-width: 100%;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/styles/css/tree.css
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/css/tree.css b/lens-ui/app/styles/css/tree.css
new file mode 100644
index 0000000..402c9a0
--- /dev/null
+++ b/lens-ui/app/styles/css/tree.css
@@ -0,0 +1,51 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+
+ .node {
+  font-weight: bold;
+}
+
+.treeNode.measureNode, .treeNode.childNode {
+  color: blue;
+}
+
+.treeNode.dimensionNode {
+  color: darkgreen;
+}
+
+.quiet {
+  color: #666;
+}
+
+.treeNode:hover {
+  background-color: #eee;
+}
+
+.page-next, .page-back {
+  margin: 2px 8px;
+  cursor: pointer;
+}
+
+div.tree-view {
+  -o-text-overflow: ellipsis;   /* Opera */
+  text-overflow:    ellipsis;   /* IE, Safari (WebKit) */
+  overflow:hidden;              /* don't show excess chars */
+  white-space:nowrap;           /* force single line */
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/styles/less/globals.less
----------------------------------------------------------------------
diff --git a/lens-ui/app/styles/less/globals.less b/lens-ui/app/styles/less/globals.less
new file mode 100644
index 0000000..c0704dc
--- /dev/null
+++ b/lens-ui/app/styles/less/globals.less
@@ -0,0 +1,23 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+
+ // IMPORTS
+
+@import "~bootstrap/less/bootstrap.less";

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/config.json
----------------------------------------------------------------------
diff --git a/lens-ui/config.json b/lens-ui/config.json
new file mode 100644
index 0000000..3316bf6
--- /dev/null
+++ b/lens-ui/config.json
@@ -0,0 +1,4 @@
+{
+  "isPersistent": true,
+  "baseURL": "/serverproxy/"
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/index.html
----------------------------------------------------------------------
diff --git a/lens-ui/index.html b/lens-ui/index.html
new file mode 100644
index 0000000..9c20fe9
--- /dev/null
+++ b/lens-ui/index.html
@@ -0,0 +1,100 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <base href="/">
+    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
+    <title>LENS UI</title>
+
+    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
+    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
+    <!--[if lt IE 9]>
+      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
+      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
+    <![endif]-->
+
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
+
+    <!-- style for the loader till JavaScript downloads-->
+    <style>
+      .loading-no-js {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+      }
+      .loading-bar {
+        display: inline-block;
+        width: 6px;
+        height: 36px;
+        border-radius: 4px;
+        animation: loading 1s ease-in-out infinite;
+      }
+      .loading-bar:nth-child(1) {
+        background-color: #3498db;
+        animation-delay: 0;
+      }
+      .loading-bar:nth-child(2) {
+        background-color: #c0392b;
+        animation-delay: 0.09s;
+      }
+      .loading-bar:nth-child(3) {
+        background-color: #f1c40f;
+        animation-delay: .18s;
+      }
+      .loading-bar:nth-child(4) {
+        background-color: #27ae60;
+        animation-delay: .27s;
+      }
+
+      @keyframes loading {
+        0% {
+          transform: scale(1);
+        }
+        20% {
+          transform: scale(1, 2.2);
+        }
+        40% {
+          transform: scale(1);
+        }
+      }
+    </style>
+  </head>
+  <body>
+
+  <div class="loading-no-js" id="loader-no-js">
+    <div class="loading-bar"></div>
+    <div class="loading-bar"></div>
+    <div class="loading-bar"></div>
+    <div class="loading-bar"></div>
+  </div>
+
+    <!-- everything goes into this section. Do anything but touch this. I dare you!-->
+    <section id="app">
+
+    </section>
+
+    <script src="target/assets/bundle.js"></script>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/package.json
----------------------------------------------------------------------
diff --git a/lens-ui/package.json b/lens-ui/package.json
new file mode 100644
index 0000000..920b120
--- /dev/null
+++ b/lens-ui/package.json
@@ -0,0 +1,51 @@
+{
+  "name": "lens-ui",
+  "version": "1.0.0",
+  "description": "An exemplary front end solution for Apache LENS",
+  "main": "app/app.js",
+  "scripts": {
+    "start": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p && lensserver='http://0.0.0.0:9999/lensapi/' port=8082 node server.js",
+    "dev": "lensserver='http://0.0.0.0:9999/lensapi/' port=8082 node server.js & node_modules/webpack/bin/webpack.js --watch",
+    "deploy": "NODE_ENV=production node_modules/webpack/bin/webpack.js -p"
+  },
+  "dependencies": {
+    "bluebird": "^2.9.34",
+    "bootstrap": "^3.3.4",
+    "classnames": "^2.1.2",
+    "codemirror": "^5.3.0",
+    "flux": "^2.0.3",
+    "halogen": "^0.1.8",
+    "keymirror": "^0.1.1",
+    "lodash": "^3.9.1",
+    "moment": "^2.10.3",
+    "object-assign": "^2.0.0",
+    "q": "^1.4.1",
+    "react": "^0.13.3",
+    "react-bootstrap": "^0.22.6",
+    "react-router": "^0.13.3",
+    "react-treeview": "^0.3.12",
+    "reqwest": "^1.1.5"
+  },
+  "devDependencies": {
+    "autoprefixer-loader": "^1.2.0",
+    "babel-core": "^5.4.3",
+    "babel-loader": "^5.3.2",
+    "babel-runtime": "^5.7.0",
+    "body-parser": "^1.13.2",
+    "cookie-parser": "^1.3.5",
+    "css-loader": "^0.13.1",
+    "express": "^4.12.4",
+    "express-session": "^1.11.3",
+    "file-loader": "^0.8.1",
+    "http-proxy": "^1.11.1",
+    "json-loader": "^0.5.2",
+    "less": "^2.5.0",
+    "less-loader": "^2.2.0",
+    "morgan": "^1.6.1",
+    "node-libs-browser": "^0.5.0",
+    "serve-favicon": "^2.3.0",
+    "style-loader": "^0.12.2",
+    "url-loader": "^0.5.5",
+    "webpack": "^1.9.7"
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/pom.xml
----------------------------------------------------------------------
diff --git a/lens-ui/pom.xml b/lens-ui/pom.xml
new file mode 100644
index 0000000..69bcee5
--- /dev/null
+++ b/lens-ui/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <name>Lens UI</name>
+  <parent>
+    <artifactId>apache-lens</artifactId>
+    <groupId>org.apache.lens</groupId>
+    <version>2.4.0-beta-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>lens-ui</artifactId>
+  <packaging>pom</packaging>
+  <description>Lens UI client</description>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>${antrun.plugin.version}</version>
+        <configuration>
+          <target>
+            <zip destfile="target/${project.artifactId}-${project.version}" basedir="${project.basedir}" excludes="target/**" />
+          </target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>com.github.eirslett</groupId>
+        <artifactId>frontend-maven-plugin</artifactId>
+        <version>${frontend.maven.plugin}</version>
+        <executions>
+          <execution>
+            <id>install node and npm</id>
+            <goals>
+              <goal>install-node-and-npm</goal>
+            </goals>
+            <configuration>
+              <nodeVersion>${nodeVersion}</nodeVersion>
+              <npmVersion>${npmVersion}</npmVersion>
+              <nodeDownloadRoot>https://nodejs.org/dist/</nodeDownloadRoot>
+              <npmDownloadRoot>http://registry.npmjs.org/npm/-/</npmDownloadRoot>
+              <installDirectory>node</installDirectory>
+            </configuration>
+          </execution>
+          <execution>
+            <id>npm install</id>
+            <goals>
+              <goal>npm</goal>
+            </goals>
+            <!-- Optional configuration which provides for running any npm command -->
+            <configuration>
+              <arguments>install</arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/server.js
----------------------------------------------------------------------
diff --git a/lens-ui/server.js b/lens-ui/server.js
new file mode 100644
index 0000000..e812018
--- /dev/null
+++ b/lens-ui/server.js
@@ -0,0 +1,79 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+var express = require('express');
+var path = require('path');
+var favicon = require('serve-favicon');
+var logger = require('morgan');
+var cookieParser = require('cookie-parser');
+var bodyParser = require('body-parser');
+var session = require('express-session');
+
+var app = express();
+var httpProxy = require('http-proxy');
+var proxy = httpProxy.createProxyServer();
+var port = process.env['port'] || 8082;
+
+app.use(logger('dev'));
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: false }));
+app.use(cookieParser());
+
+process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
+
+if(!process.env['lensserver']){
+  throw new Error('Specify LENS Server address in `lensserver` argument');
+}
+
+console.log('Using this as your LENS Server Address: ', process.env['lensserver']);
+console.log('If this seems wrong, please edit `lensserver` argument in package.json. Do not forget to append http://\n');
+
+app.use( session({
+   secret            : 'SomethingYouKnow',
+   resave            : false,
+   saveUninitialized : true
+}));
+
+var fs = require('fs');
+
+app.use(express.static(path.resolve(__dirname, 'target', 'assets')));
+
+app.get('/target/assets/*', function (req, res) {
+  res.setHeader('Cache-Control', 'public');
+  res.end(fs.readFileSync(__dirname + req.path));
+});
+
+app.all('/serverproxy/*', function (req, res) {
+  req.url = req.url.replace('serverproxy', '');
+  proxy.web(req, res, {
+      target: process.env['lensserver']
+  }, function (e) { console.log('Handled error.'); });
+});
+
+app.get('*', function(req, res) {
+  res.end(fs.readFileSync(__dirname + '/index.html'));
+});
+
+var server = app.listen(port, function(err) {
+  if(err) throw err;
+
+  var port = server.address().port;
+
+  console.log('Ad hoc UI server listening at port: ', port);
+});

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/webpack.config.js
----------------------------------------------------------------------
diff --git a/lens-ui/webpack.config.js b/lens-ui/webpack.config.js
new file mode 100644
index 0000000..ab4021f
--- /dev/null
+++ b/lens-ui/webpack.config.js
@@ -0,0 +1,55 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+var webpack = require('webpack');
+var path = require('path');
+
+
+module.exports = {
+
+  entry: {
+    app: [
+      './app/app.js'
+    ]
+  },
+
+	output: {
+    path: path.join(__dirname, 'target', 'assets'),
+		filename: 'bundle.js'
+	},
+
+  plugins: [
+    new webpack.NoErrorsPlugin()
+  ],
+
+  resolve: {
+    modulesDirectories: ['app', 'node_modules', __dirname]
+  },
+
+	module: {
+		loaders: [
+      { test: /\.jsx?$/, loaders: ['babel'], include: path.join(__dirname, 'app') },
+			{ test: /\.css$/, loaders: ['style', 'css'] },
+      { test: /\.less$/, loaders: ['style', 'css', 'autoprefixer', 'less'] },
+      { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loaders: ['url?limit=10000&minetype=application/font-woff'] },
+      { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loaders: ['file'] },
+      { test: /\.json$/, loaders: ['json']}
+		]
+	}
+};

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 10f9bc1..dd26713 100644
--- a/pom.xml
+++ b/pom.xml
@@ -107,6 +107,11 @@
     <antrun.plugin.version>1.8</antrun.plugin.version>
     <cobertura.plugin.version>2.7</cobertura.plugin.version>
 
+    <!-- UI -->
+    <frontend.maven.plugin>0.0.23</frontend.maven.plugin>
+    <nodeVersion>v4.0.0</nodeVersion>
+    <npmVersion>2.7.6</npmVersion>
+
     <!-- debian -->
     <mvn.deb.build.dir>${project.build.directory}/debian</mvn.deb.build.dir>
 
@@ -547,6 +552,8 @@
             <exclude>**/*.iml</exclude>
             <exclude>**/.classpath</exclude>
             <exclude>**/.project</exclude>
+            <exclude>**/node/**</exclude>
+            <exclude>**/node_modules/**</exclude>
             <exclude>**/.checkstyle</exclude>
             <exclude>**/.settings/**</exclude>
             <exclude>**/maven-eclipse.xml</exclude>
@@ -567,6 +574,7 @@
             <exclude>**/codemirror.min.*</exclude>
             <exclude>**/*.js</exclude>
             <exclude>**/*.properties</exclude>
+            <exclude>**/*.json</exclude>
           </excludes>
         </configuration>
         <executions>
@@ -1522,6 +1530,7 @@
     <module>lens-ml-lib</module>
     <module>lens-ml-dist</module>
     <module>lens-regression</module>
+    <module>lens-ui</module>
   </modules>
 
   <profiles>


[14/50] [abbrv] lens git commit: LENS-737 : Throw single error out with LensMultiException

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
index 603d7cb..ac1c558 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
@@ -31,7 +31,9 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.error.LensError;
 import org.apache.lens.api.result.LensAPIResult;
 import org.apache.lens.api.result.LensErrorTO;
+import org.apache.lens.server.api.LensErrorInfo;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 
 import lombok.Getter;
@@ -41,14 +43,28 @@ import lombok.NonNull;
  * The Class LensException.
  */
 @SuppressWarnings("serial")
-public class LensException extends Exception {
+public class LensException extends Exception implements Comparable<LensException> {
 
   private static final int DEFAULT_LENS_EXCEPTION_ERROR_CODE = INTERNAL_SERVER_ERROR.getValue();
+  private static final int DEFAULT_LENS_EXCEPTION_WEIGHT = 0;
+
+  private static  LensErrorInfo defaultErrorInfo =
+      new LensErrorInfo(DEFAULT_LENS_EXCEPTION_ERROR_CODE, DEFAULT_LENS_EXCEPTION_WEIGHT, INTERNAL_SERVER_ERROR.name());
 
-  @Getter
-  private final int errorCode;
   private Object[] errorMsgFormattingArgs = new Object[0];
 
+  @Getter
+  private final LensErrorInfo errorInfo;
+
+  public int getErrorCode() {
+    return errorInfo.getErrorCode();
+  }
+
+  public int getErrorWeight() {
+    return errorInfo.getErrorWeight();
+  }
+
+
   /**
    * The lensResponse prepared by {@link #buildLensErrorResponse(ErrorCollection, String, String)}
    * */
@@ -61,7 +77,7 @@ public class LensException extends Exception {
    * @see Exception#Exception(String)
    */
   public LensException(String errorMsg) {
-    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
+    this(errorMsg, defaultErrorInfo);
   }
 
   /**
@@ -70,7 +86,7 @@ public class LensException extends Exception {
    * @see Exception#Exception(String, Throwable)
    */
   public LensException(String errorMsg, Throwable cause) {
-    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
+    this(errorMsg, defaultErrorInfo, cause);
   }
 
   /**
@@ -79,7 +95,7 @@ public class LensException extends Exception {
    * @see Exception#Exception()
    */
   public LensException() {
-    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
+    this(null, defaultErrorInfo);
   }
 
   /**
@@ -88,79 +104,100 @@ public class LensException extends Exception {
    * @see Exception#Exception(Throwable)
    */
   public LensException(Throwable cause) {
-    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
+    this(defaultErrorInfo, cause);
   }
 
   /**
-   * Constructs a new Lens Exception with error code.
+   * Constructs a new Lens Exception with error info.
    *
    * @see Exception#Exception()
    */
-  public LensException(final int errorCode) {
-    this(null, errorCode);
+  public LensException(final LensErrorInfo errorInfo) {
+    this(null, errorInfo);
   }
 
   /**
-   * Constructs a new Lens Exception with error msg and error code.
+   * Constructs a new Lens Exception with error msg and error info.
    *
    * @see Exception#Exception()
    */
-  public LensException(final String errorMsg, final int errorCode) {
-    this(errorMsg, errorCode, null);
+  public LensException(final String errorMsg, final LensErrorInfo errorInfo) {
+    this(errorMsg, errorInfo, null);
   }
 
   /**
-   * Constructs a new Lens Exception with error code, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with error info, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final int errorCode, final Throwable cause, @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorCode, cause, errorMsgFormattingArgs);
+  public LensException(final LensErrorInfo errorInfo, final Throwable cause,
+      @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorInfo, cause, errorMsgFormattingArgs);
   }
 
   /**
-   * Constructs a new Lens Exception with error code and error msg formatting arguments.
+   * Constructs a new Lens Exception with error info and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final int errorCode, @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorCode, null, errorMsgFormattingArgs);
+  public LensException(final LensErrorInfo errorInfo, @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorInfo, null, errorMsgFormattingArgs);
   }
 
-
   /**
-   * Constructs a new Lens Exception with exception error message, error code, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with exception error message, error info, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final String errorMsg, final int errorcode, final Throwable cause,
+  public LensException(final String errorMsg, final LensErrorInfo errorInfo, final Throwable cause,
     @NonNull final Object... errorMsgFormattingArgs) {
 
-    super(errorMsg, cause);
-    checkArgument(errorcode > 0);
+    super(getErrorMessage(errorMsg, errorInfo, errorMsgFormattingArgs), cause);
+    checkArgument(errorInfo.getErrorCode() > 0);
 
-    this.errorCode = errorcode;
+    this.errorInfo =  errorInfo;
     this.errorMsgFormattingArgs = errorMsgFormattingArgs;
   }
 
+  private static String getErrorMessage(final String errorMsg, final LensErrorInfo errorInfo,
+      @NonNull final Object... errorMsgFormattingArgs) {
+
+    if (StringUtils.isBlank(errorMsg)) {
+      StringBuilder error = new StringBuilder(errorInfo.getErrorName());
+      if (errorMsgFormattingArgs != null && errorMsgFormattingArgs.length != 0) {
+        error.append(Arrays.asList(errorMsgFormattingArgs));
+      }
+      return error.toString();
+    }
+    return errorMsg;
+  }
+
+  /**
+   * Copy Constructor
+   * @param e
+   */
+  public LensException(LensException e) {
+    this(e.getMessage(), e.getErrorInfo(), e.getCause(), e.errorMsgFormattingArgs);
+  }
+
   public final void buildLensErrorResponse(final ErrorCollection errorCollection,
     final String apiVersion, final String id) {
 
-    final LensError lensError = errorCollection.getLensError(errorCode);
+    final LensError lensError = errorCollection.getLensError(getErrorCode());
     final LensErrorTO lensErrorTO = buildLensErrorTO(errorCollection, lensError);
     lensAPIResult = LensAPIResult.composedOf(apiVersion, id, lensErrorTO, lensError.getHttpStatusCode());
   }
 
   public final LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection) {
 
-    final LensError lensError = errorCollection.getLensError(errorCode);
+    final LensError lensError = errorCollection.getLensError(getErrorCode());
     return buildLensErrorTO(errorCollection, lensError);
   }
 
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
     final String stackTrace) {
 
-    return LensErrorTO.composedOf(errorCode, errorMsg, stackTrace);
+    return LensErrorTO.composedOf(getErrorCode(), errorMsg, stackTrace);
   }
 
   private LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final LensError lensError) {
@@ -182,7 +219,7 @@ public class LensException extends Exception {
     }
 
     LensException e = (LensException) o;
-    if (errorCode == e.errorCode && isErrorMsgEqual(e)
+    if (errorInfo.equals(e.errorInfo) && isErrorMsgEqual(e)
       && Arrays.deepEquals(errorMsgFormattingArgs, e.errorMsgFormattingArgs)) {
       return true;
     }
@@ -216,7 +253,7 @@ public class LensException extends Exception {
     final int PRIME = 59;
     int result = 1;
 
-    result = result * PRIME + errorCode;
+    result = result * PRIME + errorInfo.hashCode();
     result = result * PRIME + (this.getMessage() == null ? 0 : this.getMessage().hashCode());
     result = result * PRIME + Arrays.deepHashCode(errorMsgFormattingArgs);
     return result;
@@ -228,4 +265,9 @@ public class LensException extends Exception {
     }
     return new LensException(e);
   }
+
+  @Override
+  public int compareTo(LensException e) {
+    return this.getErrorWeight() - e.getErrorWeight();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
index af9e33a..5248489 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
@@ -18,10 +18,7 @@
  */
 package org.apache.lens.server.api.error;
 
-import static org.apache.lens.api.error.LensCommonErrorCode.INTERNAL_SERVER_ERROR;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -29,6 +26,7 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.result.LensErrorTO;
 
 import com.google.common.collect.ImmutableList;
+
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NonNull;
@@ -50,14 +48,14 @@ public class LensMultiCauseException extends LensException {
   @Getter(AccessLevel.PROTECTED)
   private final ImmutableList<LensException> causes;
 
-  public LensMultiCauseException(final String errMsg, @NonNull
-    final ImmutableList<LensException> causes) {
-
-    super(errMsg, INTERNAL_SERVER_ERROR.getValue());
-    checkArgument(causes.size() >= 2, "LensMultiCauseException should only be created when there are atleast "
-        + "two causes. An instance of LensException should be sufficient if there is only one cause.");
+  public LensMultiCauseException(@NonNull final ImmutableList<LensException> excpList) {
+    super(getAppropriateError(excpList));
+    this.causes = excpList;
+  }
 
-    this.causes = causes;
+  // Get appropriate error code
+  public static LensException getAppropriateError(final ImmutableList<LensException> excpList) {
+    return Collections.max(excpList);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
index 917eba3..dc20f0f 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
@@ -18,20 +18,22 @@
  */
 package org.apache.lens.server.error;
 
+import org.apache.lens.server.api.LensErrorInfo;
+
 public enum LensServerErrorCode {
 
-  SESSION_ID_NOT_PROVIDED(2001),
-  NULL_OR_EMPTY_OR_BLANK_QUERY(2002),
-  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003);
+  SESSION_ID_NOT_PROVIDED(2001, 0),
+  NULL_OR_EMPTY_OR_BLANK_QUERY(2002, 0),
+  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003, 0);
 
-  public int getValue() {
-    return this.errorCode;
+  public LensErrorInfo getLensErrorInfo() {
+    return this.errorInfo;
   }
 
-  private LensServerErrorCode(final int code) {
-    this.errorCode = code;
+  LensServerErrorCode(final int code, final int weight) {
+    this.errorInfo = new LensErrorInfo(code, weight, name());
   }
 
-  private final int errorCode;
+  private final LensErrorInfo errorInfo;
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
index 366b306..d90f8fd 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
@@ -31,11 +31,11 @@ public class UnSupportedQuerySubmitOpException extends LensException {
   private final SupportedQuerySubmitOperations supportedOps = new SupportedQuerySubmitOperations();
 
   public UnSupportedQuerySubmitOpException() {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue());
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo());
   }
 
   public UnSupportedQuerySubmitOpException(final Throwable cause) {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(), cause);
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo(), cause);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index c29a1ac..23cc748 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -1275,7 +1275,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           final LensException firstCause = causes.get(0);
           for (LensException cause : causes) {
             if (!cause.equals(firstCause)) {
-              throw new LensMultiCauseException(StringUtils.join(failureCauses, '\n'), ImmutableList.copyOf(causes));
+              throw new LensMultiCauseException(ImmutableList.copyOf(causes));
             }
           }
           throw firstCause;
@@ -1555,15 +1555,11 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       if (prepared != null) {
         destroyPreparedQuery(prepared);
       }
-      log.error("Explain and prepare failed", e);
-      QueryPlan plan;
-      if (e.getCause() != null && e.getCause().getMessage() != null) {
-        plan = new QueryPlan(true, e.getCause().getMessage());
-      } else {
-        plan = new QueryPlan(true, e.getMessage());
-      }
-      return plan;
+      throw e;
     } catch (UnsupportedEncodingException e) {
+      if (prepared != null) {
+        destroyPreparedQuery(prepared);
+      }
       throw new LensException(e);
     } finally {
       release(sessionHandle);
@@ -2259,25 +2255,16 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public QueryPlan explain(final String requestId, LensSessionHandle sessionHandle, String query, LensConf lensConf)
     throws LensException {
     try {
-      log.info("Explain: session:{} query:{}",  sessionHandle, query);
+      log.info("Explain: session:{} query:{}", sessionHandle, query);
       acquire(sessionHandle);
       Configuration qconf = getLensConf(sessionHandle, lensConf);
-      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query,
-        getSession(sessionHandle).getLoggedInUser(), lensConf, qconf, drivers.values());
+      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query, getSession(sessionHandle)
+          .getLoggedInUser(), lensConf, qconf, drivers.values());
       explainQueryContext.setLensSessionIdentifier(sessionHandle.getPublicId().toString());
       accept(query, qconf, SubmitOp.EXPLAIN);
       rewriteAndSelect(explainQueryContext);
       addSessionResourcesToDriver(explainQueryContext);
       return explainQueryContext.getSelectedDriver().explain(explainQueryContext).toQueryPlan();
-    } catch (LensException e) {
-      log.error("Error during explain :", e);
-      QueryPlan plan;
-      if (e.getCause() != null && e.getCause().getMessage() != null) {
-        plan = new QueryPlan(true, e.getCause().getMessage());
-      } else {
-        plan = new QueryPlan(true, e.getMessage());
-      }
-      return plan;
     } catch (UnsupportedEncodingException e) {
       throw new LensException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
index 6bfd77a..96f6aea 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
@@ -77,7 +77,7 @@ public class QueryServiceResource {
 
   private void validateSessionId(final LensSessionHandle sessionHandle) throws LensException {
     if (sessionHandle == null) {
-      throw new LensException(SESSION_ID_NOT_PROVIDED.getValue());
+      throw new LensException(SESSION_ID_NOT_PROVIDED.getLensErrorInfo());
     }
   }
 
@@ -104,7 +104,7 @@ public class QueryServiceResource {
 
   private void validateQuery(String query) throws LensException {
     if (StringUtils.isBlank(query)) {
-      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue());
+      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo());
     }
   }
   /**
@@ -340,19 +340,24 @@ public class QueryServiceResource {
    * @return {@link QueryPrepareHandle} incase of {link org.apache.lens.api.query.SubmitOp#PREPARE} operation.
    *         {@link QueryPlan} incase of {@link org.apache.lens.api.query.SubmitOp#EXPLAIN_AND_PREPARE}
    *         and the query plan will contain the prepare handle as well.
+   * @throws LensException
    */
   @POST
   @Path("preparedqueries")
   @Consumes({MediaType.MULTIPART_FORM_DATA})
   @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
   @MultiPurposeResource(formParamName = "operation")
-  public QuerySubmitResult prepareQuery(@FormDataParam("sessionid") LensSessionHandle sessionid,
-    @FormDataParam("query") String query, @DefaultValue("") @FormDataParam("operation") String operation,
-    @FormDataParam("conf") LensConf conf, @DefaultValue("") @FormDataParam("queryName") String queryName) {
+  public LensAPIResult<? extends QuerySubmitResult> prepareQuery(
+      @FormDataParam("sessionid") LensSessionHandle sessionid, @FormDataParam("query") String query,
+      @DefaultValue("") @FormDataParam("operation") String operation, @FormDataParam("conf") LensConf conf,
+      @DefaultValue("") @FormDataParam("queryName") String queryName) throws LensException {
+    final String requestId = this.logSegregationContext.getLogSegragationId();
+
     try {
       checkSessionId(sessionid);
       checkQuery(query);
       SubmitOp sop = null;
+      QuerySubmitResult result;
       try {
         sop = SubmitOp.valueOf(operation.toUpperCase());
       } catch (IllegalArgumentException e) {
@@ -363,17 +368,20 @@ public class QueryServiceResource {
       }
       switch (sop) {
       case PREPARE:
-        return queryServer.prepare(sessionid, query, conf, queryName);
+        result = queryServer.prepare(sessionid, query, conf, queryName);
+        break;
       case EXPLAIN_AND_PREPARE:
-        return queryServer.explainAndPrepare(sessionid, query, conf, queryName);
+        result = queryServer.explainAndPrepare(sessionid, query, conf, queryName);
+        break;
       default:
         throw new BadRequestException("Invalid operation type: " + operation + prepareClue);
       }
+      return LensAPIResult.composedOf(null, requestId, result);
     } catch (LensException e) {
-      throw new WebApplicationException(e);
+      e.buildLensErrorResponse(errorCollection, null, requestId);
+      throw e;
     }
   }
-
   /**
    * Destroy all the prepared queries; Can be filtered with user.
    *
@@ -390,10 +398,11 @@ public class QueryServiceResource {
    */
   @DELETE
   @Path("preparedqueries")
-  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
+  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
   public APIResult destroyPreparedQueries(@QueryParam("sessionid") LensSessionHandle sessionid,
-    @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
-    @DefaultValue("-1") @QueryParam("fromDate") long fromDate, @DefaultValue("-1") @QueryParam("toDate") long toDate) {
+      @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
+      @DefaultValue("-1") @QueryParam("fromDate") long fromDate,
+      @DefaultValue("-1") @QueryParam("toDate") long toDate) {
     checkSessionId(sessionid);
     int numDestroyed = 0;
     boolean failed = false;

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
index 38b5ea0..4d4f137 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
@@ -49,7 +49,7 @@ public class ErrorResponseExpectedData {
 
     /* Assert Equal LensErrorTO (stack trace gets excluded in equality check) */
     final LensErrorTO actualLensErrorTO = lensAPIResult.getLensErrorTO();
-    assertEquals(actualLensErrorTO, expectedLensErrorTO);
+    assertEquals(actualLensErrorTO.getMessage(), expectedLensErrorTO.getMessage());
 
     /* Assert receipt of valid stacktraces */
     assertTrue(lensAPIResult.areValidStackTracesPresent(), "Received Lens Response:" + lensAPIResult);

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
index 64a75ce..2f74ceb 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
@@ -34,7 +34,7 @@ public class FailingQueryDriver extends MockDriver {
     if (ctx.getUserQuery().contains("fail")) {
       return new FactPartitionBasedQueryCost(0.0);
     } else {
-      throw new LensException();
+      throw new LensException("Simulated Estimate Failure");
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
index 2189eb8..18a8c8d 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
@@ -111,8 +111,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.<LensSessionHandle>absent(), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Session id not provided. Please provide a session id.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SESSION_ID_NOT_PROVIDED.getValue(), expectedErrMsg,
-      MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        SESSION_ID_NOT_PROVIDED.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -126,8 +126,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), testQuery);
 
     final String expectedErrMsg = "Query is not provided, or it is empty or blank. Please provide a valid query.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue(), expectedErrMsg,
-      MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -144,7 +144,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     final String expectedErrMsg = "Provided Operation is not supported. Supported Operations are: "
       + "[estimate, execute, explain, execute_with_timeout]";
 
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo().getErrorCode(),
       expectedErrMsg, MOCK_STACK_TRACE, new SupportedQuerySubmitOperations());
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -165,11 +166,9 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       expectedErrMsg, MOCK_STACK_TRACE);
     LensErrorTO childError2 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
         expectedErrMsg, MOCK_STACK_TRACE);
-    LensErrorTO childError3 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE);
 
     LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2, childError3));
+        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2));
 
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(Status.INTERNAL_SERVER_ERROR,
       expectedLensErrorTO);
@@ -185,7 +184,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Syntax Error: line 1:0 cannot recognize input near 'mock' '-' 'query'";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getValue(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getLensErrorInfo().getErrorCode(),
       expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -290,8 +289,9 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       final ColUnAvailableInTimeRange expectedErrorPayload = new ColUnAvailableInTimeRange(testDimensionField,
         expecAvailableFrom, expecAvailableTill);
 
-      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
+      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+          COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
+          expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
       ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
       expectedData.verify(response);

http://git-wip-us.apache.org/repos/asf/lens/blob/ab74f6ea/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index b3f5d93..fa8d6ee 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -375,7 +375,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
+        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
     assertEquals(plan2.getTablesQueried().size(), 1);
     assertTrue(plan2.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan2.getPrepareHandle());
@@ -387,47 +387,41 @@ public class TestQueryService extends LensJerseyTest {
    * Test explain failure.
    *
    * @throws InterruptedException the interrupted exception
+   * @throws UnsupportedEncodingException
    */
   @Test
-  public void testExplainFailure() throws InterruptedException {
+  public void testExplainFailure() throws InterruptedException, UnsupportedEncodingException {
     final WebTarget target = target().path("queryapi/queries");
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(),
-      "select NO_ID from " + TEST_TABLE));
+        MediaType.APPLICATION_XML_TYPE));
+    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
+        + TEST_TABLE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
 
-    final QueryPlan plan = target.request()
-      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
-    assertTrue(plan.isError());
-    assertNotNull(plan.getErrorMsg());
-    assertTrue(plan.getErrorMsg()
-      .contains("Invalid table alias or column reference 'NO_ID': " + "(possible column names are: id, idstr)"));
+    final Response responseExplain = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    assertEquals(responseExplain.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
 
     // Test explain and prepare
     final WebTarget ptarget = target().path("queryapi/preparedqueries");
 
     final FormDataMultiPart mp2 = new FormDataMultiPart();
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-      + TEST_TABLE));
+        + TEST_TABLE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain_and_prepare"));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-      MediaType.APPLICATION_XML_TYPE));
+        MediaType.APPLICATION_XML_TYPE));
 
-    final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPlan.class);
-    assertTrue(plan2.isError());
-    assertNotNull(plan2.getErrorMsg());
-    assertNull(plan2.getPrepareHandle());
-    assertTrue(plan2.getErrorMsg().contains("Invalid table alias or column reference 'NO_ID': "
-      + "(possible column names are: id, idstr)"));
+    final Response responseExplainAndPrepare = target.request().post(
+        Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+
+    assertEquals(responseExplainAndPrepare.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
   }
 
   // post to preparedqueries
@@ -457,7 +451,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPrepareHandle pHandle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-      QueryPrepareHandle.class);
+        new GenericType<LensAPIResult<QueryPrepareHandle>>() {}).getData();
 
     // Get all prepared queries
     List<QueryPrepareHandle> allQueries = (List<QueryPrepareHandle>) target.queryParam("sessionid", lensSessionId)
@@ -555,7 +549,9 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan = target.request()
-      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), QueryPlan.class);
+      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
+          new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+
     assertEquals(plan.getTablesQueried().size(), 1);
     assertTrue(plan.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan.getPrepareHandle());
@@ -1425,7 +1421,9 @@ public class TestQueryService extends LensJerseyTest {
     final Response response = target.request()
       .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
 
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue(),
+
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
+        LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo().getErrorCode(),
       "Neither cube nor dimensions accessed in the query", TestDataUtils.MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 


[43/50] [abbrv] lens git commit: LENS-792: Improve StatusPoller logging to reduce noise

Posted by ra...@apache.org.
LENS-792: Improve StatusPoller logging to reduce noise


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/2ecef112
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/2ecef112
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/2ecef112

Branch: refs/heads/current-release-line
Commit: 2ecef112f49aa45521a4b5a81802d265d0e34129
Parents: 5c9bae0
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Tue Oct 6 15:35:59 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Tue Oct 6 15:35:59 2015 +0530

----------------------------------------------------------------------
 .../main/java/org/apache/lens/server/api/query/QueryContext.java | 3 +++
 .../org/apache/lens/server/query/QueryExecutionServiceImpl.java  | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2ecef112/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index 3a5b887..ac94207 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -43,11 +43,13 @@ import com.google.common.collect.Lists;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * The Class QueryContext.
  */
 @ToString
+@Slf4j
 public class QueryContext extends AbstractQueryContext {
 
   /**
@@ -334,6 +336,7 @@ public class QueryContext extends AbstractQueryContext {
 
   public synchronized void setStatus(final QueryStatus newStatus) throws LensException {
     validateTransition(newStatus);
+    log.info("Updating status of {} from {} to {}", getQueryHandle(), this.status, newStatus);
     this.status = newStatus;
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/2ecef112/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index ea19742..73179e1 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -670,7 +670,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             }
 
             logSegregationContext.setLogSegragationAndQueryId(ctx.getQueryHandleString());
-            log.info("Polling status for {}", ctx.getQueryHandle());
+            log.debug("Polling status for {}", ctx.getQueryHandle());
             try {
               // session is not required to update status of the query
               // don't need to wrap this with acquire/release
@@ -770,7 +770,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       synchronized (ctx) {
         QueryStatus before = ctx.getStatus();
         if (!ctx.queued() && !ctx.finished() && !ctx.getDriverStatus().isFinished()) {
-          log.info("Updating status for {}", ctx.getQueryHandle());
+          log.debug("Updating status for {}", ctx.getQueryHandle());
           try {
             ctx.getSelectedDriver().updateStatus(ctx);
             ctx.setStatus(ctx.getDriverStatus().toQueryStatus());


[20/50] [abbrv] lens git commit: LENS-742 : Adds query feature : Saved query and parameterization

Posted by ra...@apache.org.
LENS-742 : Adds query feature : Saved query and parameterization


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/4e81ef4d
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/4e81ef4d
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/4e81ef4d

Branch: refs/heads/current-release-line
Commit: 4e81ef4ddfef2d8c89c48576e474c2094cbbc56b
Parents: 4addd7b
Author: Amruth S <am...@gmail.com>
Authored: Tue Sep 15 18:05:20 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Tue Sep 15 18:05:20 2015 +0530

----------------------------------------------------------------------
 .../lens/api/error/LensCommonErrorCode.java     |  10 +-
 .../lens/api/query/save/ListResponse.java       |  51 ++
 .../apache/lens/api/query/save/Parameter.java   |  80 +++
 .../api/query/save/ParameterCollectionType.java |  40 ++
 .../lens/api/query/save/ParameterDataType.java  |  48 ++
 .../api/query/save/ParameterParserResponse.java |  50 ++
 .../query/save/ResourceModifiedResponse.java    |  70 +++
 .../apache/lens/api/query/save/SavedQuery.java  |  70 +++
 lens-api/src/main/resources/lens-errors.conf    |  27 ++
 .../lens/server/api/LensConfConstants.java      |  16 +
 .../server/api/query/save/SavedQueryHelper.java |  93 ++++
 .../api/query/save/SavedQueryService.java       |  94 ++++
 .../exception/MissingParameterException.java    |  46 ++
 .../exception/ParameterCollectionException.java |  53 ++
 .../save/exception/ParameterValueException.java |  51 ++
 .../save/exception/PrivilegeException.java      |  51 ++
 .../save/exception/SavedQueryNotFound.java      |  45 ++
 .../save/exception/ValueEncodeException.java    |  49 ++
 .../param/ParameterCollectionTypeEncoder.java   |  70 +++
 .../save/param/ParameterDataTypeEncoder.java    |  91 ++++
 .../api/query/save/param/ParameterParser.java   | 135 ++++++
 .../api/query/save/param/ParameterResolver.java | 126 +++++
 .../api/query/save/TestParameterParser.java     |  79 +++
 .../api/query/save/TestParameterResolution.java | 176 +++++++
 lens-server/enunciate.xml                       |   1 +
 .../lens/server/query/save/SavedQueryApp.java   |  48 ++
 .../lens/server/query/save/SavedQueryDao.java   | 483 +++++++++++++++++++
 .../server/query/save/SavedQueryResource.java   | 307 ++++++++++++
 .../query/save/SavedQueryServiceImpl.java       | 141 ++++++
 .../apache/lens/server/util/UtilityMethods.java |  19 +-
 .../src/main/resources/lensserver-default.xml   |  33 +-
 .../query/save/TestSavedQueryService.java       | 274 +++++++++++
 lens-server/src/test/resources/lens-site.xml    |  22 +-
 src/site/apt/admin/config.apt                   |  92 ++--
 src/site/apt/user/index.apt                     |  23 +
 35 files changed, 3017 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/error/LensCommonErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/error/LensCommonErrorCode.java b/lens-api/src/main/java/org/apache/lens/api/error/LensCommonErrorCode.java
index 754e6e1..9c5eaf5 100644
--- a/lens-api/src/main/java/org/apache/lens/api/error/LensCommonErrorCode.java
+++ b/lens-api/src/main/java/org/apache/lens/api/error/LensCommonErrorCode.java
@@ -26,7 +26,15 @@ public enum LensCommonErrorCode {
 
   INTERNAL_SERVER_ERROR(1001),
 
-  INVALID_XML_ERROR(1002);
+  INVALID_XML_ERROR(1002),
+
+  RESOURCE_NOT_FOUND(1003),
+
+  NOT_AUTHORIZED(1004),
+
+  MISSING_PARAMETERS(1005),
+
+  INVALID_PARAMETER_VALUE(1006);
 
   public int getValue() {
     return this.errorCode;

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/ListResponse.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/ListResponse.java b/lens-api/src/main/java/org/apache/lens/api/query/save/ListResponse.java
new file mode 100644
index 0000000..e707642
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/ListResponse.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Response of savedqueries list API.
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@XmlRootElement
+public class ListResponse {
+  /**
+   * The starting offset of the result set.
+   */
+  private long offsetAppplied;
+
+  /**
+   * The total number of queries returned in the current request.
+   */
+  private long totalCount;
+
+  /**
+   * The queries.
+   */
+  private List<SavedQuery> resoures;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/Parameter.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/Parameter.java b/lens-api/src/main/java/org/apache/lens/api/query/save/Parameter.java
new file mode 100644
index 0000000..d5f541e
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/Parameter.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang.Validate;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * The class Parameter.
+ *
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode
+@XmlRootElement
+public class Parameter {
+  /**
+   * Name of the parameter used in the query.
+   * It should match the following regex pattern ":[a-zA-Z][a-zA-Z_0-9]".
+   */
+  private String name;
+
+  /**
+   * Display name of the parameter. Should be used by the UI apps for resolution.
+   */
+  private String displayName;
+
+  /**
+   * The default value that will be used,
+   * if the parameter is not supplied with any values while running the query.
+   */
+  private String[] defaultValue;
+
+  /**
+   * Data type of the parameter. Could be number, decimal, string or boolean.
+   * The value supplied will be parsed with the corresponding data type.
+   */
+  private ParameterDataType dataType;
+
+  /**
+   * Collection type of the parameter.
+   * Depending on the type of expression IN/EQ, it could be a single/multiple collection.
+   */
+  private ParameterCollectionType collectionType;
+
+  public Parameter(String name) {
+    this.name = name;
+  }
+
+  void afterUnmarshal(Unmarshaller u, Object parent) {
+    Validate.notNull(name);
+    Validate.notNull(displayName);
+    Validate.notNull(dataType);
+    Validate.notNull(collectionType);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterCollectionType.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterCollectionType.java b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterCollectionType.java
new file mode 100644
index 0000000..971e794
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterCollectionType.java
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * The enum ParameterCollectionType
+ * Collection type of a parameter has to be chosen based on its context.
+ * - If it is occurring next to an IN/NOT IN clause, its multiple
+ * - If it is found with EQ/NEQ..>,<,>=,<=,like etc, its single
+ */
+@XmlRootElement
+public enum ParameterCollectionType {
+  /**
+   * Single valued parameter.
+   */
+  SINGLE,
+
+  /**
+   * Multivalued parameter.
+   */
+  MULTIPLE;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterDataType.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterDataType.java b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterDataType.java
new file mode 100644
index 0000000..550e89b
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterDataType.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * The enum ParameterDataType
+ * Should be given based on the column data type.
+ */
+@XmlRootElement
+public enum ParameterDataType {
+  /**
+   * String data type
+   */
+  STRING,
+
+  /**
+   * Number data type
+   */
+  NUMBER,
+
+  /**
+   * Decimal data type
+   */
+  DECIMAL,
+
+  /**
+   * Boolean data type
+   */
+  BOOLEAN;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterParserResponse.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterParserResponse.java b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterParserResponse.java
new file mode 100644
index 0000000..aa92f00
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/ParameterParserResponse.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.google.common.collect.ImmutableSet;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Response of parsing a parameterised HQL query
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@XmlRootElement
+public class ParameterParserResponse {
+  /**
+   * Flag that denotes if the query and the parameters are valid
+   */
+  private boolean valid;
+
+  /**
+   * The message
+   */
+  private String message;
+
+  /**
+   * The immutable set of parameters parsed from a parameterised HQL query
+   */
+  private ImmutableSet<Parameter> parameters;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/ResourceModifiedResponse.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/ResourceModifiedResponse.java b/lens-api/src/main/java/org/apache/lens/api/query/save/ResourceModifiedResponse.java
new file mode 100644
index 0000000..4d4f74e
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/ResourceModifiedResponse.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The response of CRUD action on resource.
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@XmlRootElement
+public class ResourceModifiedResponse {
+
+  /**
+   * Action enum that denotes the operation performed
+   */
+  public enum Action {
+    /**
+     * Resource is created
+     */
+    CREATED,
+
+    /**
+     * Resource is updated
+     */
+    UPDATED,
+
+    /**
+     * Resource is updated
+     */
+    DELETED
+  }
+
+  /**
+   * ID of the affected resource
+   */
+  private long id;
+
+  /**
+   * The resource type
+   */
+  private String resource;
+
+  /**
+   * The action performed on the reource
+   */
+  private Action status;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/java/org/apache/lens/api/query/save/SavedQuery.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/save/SavedQuery.java b/lens-api/src/main/java/org/apache/lens/api/query/save/SavedQuery.java
new file mode 100644
index 0000000..c844fe1
--- /dev/null
+++ b/lens-api/src/main/java/org/apache/lens/api/query/save/SavedQuery.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.api.query.save;
+
+import java.util.List;
+
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang.Validate;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * The class representing the saved query
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@XmlRootElement
+public class SavedQuery {
+  /**
+   * ID of the saved query (unique)
+   */
+  private long id;
+
+  /**
+   * Name of the saved query
+   */
+  private String name;
+
+  /**
+   * Description of the saved query
+   */
+  private String description;
+
+  /**
+   * The actual query. Should adhere to HQL syntax
+   */
+  private String query;
+
+  /**
+   * Parameters that are used in the query
+   */
+  private List<Parameter> parameters;
+
+  void afterUnmarshal(Unmarshaller u, Object parent) {
+    Validate.notNull(name);
+    Validate.notNull(query);
+    Validate.notNull(parameters);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-api/src/main/resources/lens-errors.conf
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/lens-errors.conf b/lens-api/src/main/resources/lens-errors.conf
index 5428041..a582dc2 100644
--- a/lens-api/src/main/resources/lens-errors.conf
+++ b/lens-api/src/main/resources/lens-errors.conf
@@ -24,6 +24,8 @@
 # Define HTTP status codes
 
 BAD_REQUEST = 400
+NOT_FOUND = 404
+UNAUTHORIZED = 401
 INTERNAL_SERVER_ERROR = 500
 
 # Define all module specific errors
@@ -43,6 +45,31 @@ lensCommonErrors = [
     httpStatusCode = ${BAD_REQUEST}
     errorMsg = "XML invalid: %s"
   }
+
+  {
+    errorCode = 1003
+    httpStatusCode = ${NOT_FOUND}
+    errorMsg = "The specified %s with identifier %s does not exist"
+  }
+
+  {
+    errorCode = 1004
+    httpStatusCode = ${UNAUTHORIZED}
+    errorMsg = "User does not have %s access to %s:%s"
+  }
+
+  {
+    errorCode = 1005
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "These parameters are missing and are required : %s"
+  }
+
+  {
+    errorCode = 1006
+    httpStatusCode = ${BAD_REQUEST}
+    errorMsg = "Value provided {%s} for parameter {%s} is invalid due to {%s}"
+  }
+
 ]
 
 # lensServerErrors: Defined for lens-server module

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index fb11f93..90aea0b 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -926,4 +926,20 @@ public final class LensConfConstants {
    */
   public static final String WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY = SERVER_PFX
       + "waiting.queries.selection.policy.factories";
+
+  /**
+   * Key denoting the dialect class property of saved query service.
+   */
+  public static final String JDBC_DIALECT_PROVIDER_CLASS_KEY = "lens.server.savedquery.jdbc.dialectclass";
+
+  /**
+   * Key denoting the default fetch value of saved query list api.
+   */
+  public static final String FETCH_COUNT_SAVED_QUERY_LIST_KEY = "lens.server.savedquery.list.default.count";
+
+  /**
+   * Default fetch count of saved query list api.
+   */
+  public static final int DEFAULT_FETCH_COUNT_SAVED_QUERY_LIST = 20;
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryHelper.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryHelper.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryHelper.java
new file mode 100644
index 0000000..04058b6
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryHelper.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.Parameter;
+import org.apache.lens.api.query.save.ParameterCollectionType;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.save.param.ParameterDataTypeEncoder;
+import org.apache.lens.server.api.query.save.param.ParameterResolver;
+
+import com.google.common.collect.Lists;
+
+public final class SavedQueryHelper {
+
+  private SavedQueryHelper() {
+
+  }
+
+  /**
+   * Extracts the default parameter values from the saved query
+   *
+   * @param query
+   * @return multivalued map of parameter values
+   */
+  public static MultivaluedMap<String, String> getDefaultParameterValues(SavedQuery query) {
+    final MultivaluedMap<String, String> defaults = new MultivaluedHashMap<>();
+    for(Parameter parameter: query.getParameters()) {
+      String[] defaultValues = parameter.getDefaultValue();
+      if (defaultValues != null && defaultValues.length !=0) {
+        defaults.addAll(parameter.getName(), defaultValues);
+      }
+    }
+    return defaults;
+  }
+
+  /**
+   * Gets a sample query for saved query by auto resolving the parameters
+   *
+   * @param savedQuery
+   * @return hql query
+   * @throws LensException
+   */
+  public static String getSampleResolvedQuery(SavedQuery savedQuery) throws LensException {
+    return ParameterResolver.resolve(savedQuery, extrapolateSampleParamValues(savedQuery));
+  }
+
+  /**
+   * Given a saved query, this method extrapolates the parameter values (using the parameter definition)
+   * and returns it as a multivalued map
+   *
+   * @param savedQuery
+   * @return multivalued map containing parameter values
+   */
+  private static MultivaluedMap<String, String> extrapolateSampleParamValues(SavedQuery savedQuery) {
+    final MultivaluedHashMap<String, String> paramValues = new MultivaluedHashMap<>();
+    for(Parameter parameter : savedQuery.getParameters()) {
+      final String sampleValue = ParameterDataTypeEncoder.valueOf(parameter.getDataType().toString()).getSampleValue();
+      if (parameter.getCollectionType() == ParameterCollectionType.SINGLE) {
+        paramValues.putSingle(
+          parameter.getName(),
+          sampleValue
+        );
+      } else if (parameter.getCollectionType() == ParameterCollectionType.MULTIPLE) {
+        paramValues.put(
+          parameter.getName(),
+          Lists.newArrayList(sampleValue, sampleValue)
+        );
+      }
+    }
+    return paramValues;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryService.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryService.java
new file mode 100644
index 0000000..cba1df6
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/SavedQueryService.java
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.ListResponse;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.error.LensException;
+
+public interface SavedQueryService {
+
+  /**
+   * The Constant NAME.
+   */
+  String NAME = "savedquery";
+
+  /**
+   * Saves a query
+   * @param query  Saved query object.
+   * @return id of the created saved query.
+   * @throws LensException
+   */
+  long save(SavedQuery query) throws LensException;
+
+  /**
+   * Updates the specified saved query with the new object.
+   * @param id     id of the saved query.
+   * @param query  Saved query object.
+   * @throws LensException
+   */
+  void update(long id, SavedQuery query) throws LensException;
+
+  /**
+   * Deletes the saved query specified.
+   * @param id id of the saved query.
+   * @throws LensException
+   */
+  void delete(long id) throws LensException;
+
+  /**
+   * Returns the saved query pointed out by the id.
+   * @param id id of the saved query.
+   * @return saved query object.
+   * @throws LensException
+   */
+  SavedQuery get(long id)  throws LensException;
+
+  /**
+   * List the saved query from {start} to {count} matching filter denoted by criteria.
+   * @param criteria  Multivalued map representing the criteria.
+   * @param start    Displacement from the first matching record.
+   * @param count     Number of records to fetch.
+   * @return list of queries.
+   * @throws LensException
+   */
+  ListResponse list(MultivaluedMap<String, String> criteria, long start, long count) throws LensException;
+
+  /**
+   * Grant permissions for users to do actions on the saved query.
+   * @param id              id of the query.
+   * @param sharingUser     User invoking this action.
+   * @param targetUserPath  Target users who have to get affected.
+   * @param privileges      Privileges to be granted.
+   * @throws LensException
+   */
+  void grant(long id, String sharingUser, String targetUserPath, String[] privileges) throws LensException;
+
+  /**
+   * Revoke permissions from users to do actions on the saved query.
+   * @param id              id of the query.
+   * @param sharingUser     User invoking this action.
+   * @param targetUserPath  Target users who have to get affected.
+   * @param privileges      Privileges to be granted.
+   * @throws LensException
+   */
+  void revoke(long id, String sharingUser, String targetUserPath, String[] privileges) throws LensException;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/MissingParameterException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/MissingParameterException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/MissingParameterException.java
new file mode 100644
index 0000000..14d3298
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/MissingParameterException.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+import static org.apache.lens.api.error.LensCommonErrorCode.MISSING_PARAMETERS;
+
+import java.util.Collection;
+
+import org.apache.lens.server.api.LensErrorInfo;
+import org.apache.lens.server.api.error.LensException;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import lombok.Getter;
+
+/**
+ * The class MissingParameterException. Thrown when a required parameter is not found.
+ */
+public class MissingParameterException extends LensException {
+
+  @Getter
+  private final ImmutableList<String> missingParameters;
+
+  public MissingParameterException(Collection<String> missingParameters) {
+    super(
+      new LensErrorInfo(MISSING_PARAMETERS.getValue(), 0, MISSING_PARAMETERS.toString())
+      , Joiner.on(",").join(missingParameters));
+    this.missingParameters = ImmutableList.copyOf(missingParameters);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterCollectionException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterCollectionException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterCollectionException.java
new file mode 100644
index 0000000..332d327
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterCollectionException.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+import java.util.List;
+
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.save.param.ParameterCollectionTypeEncoder;
+
+import com.google.common.collect.ImmutableList;
+import lombok.Getter;
+
+/**
+ * The class ParameterCollectionException. Thrown when the collection type of the parameter
+ * and the encoded values are different.
+ */
+public class ParameterCollectionException extends LensException {
+
+  @Getter
+  private final ParameterCollectionTypeEncoder collectionType;
+  @Getter
+  private final ImmutableList<String> values;
+
+  public ParameterCollectionException(
+    ParameterCollectionTypeEncoder collectionType, List<String> values, String message) {
+    super(values + " cannot be encoded as " + collectionType.name() + ", Reason : " + message);
+    this.collectionType = collectionType;
+    this.values = ImmutableList.copyOf(values);
+  }
+
+  public ParameterCollectionException(
+    ParameterCollectionTypeEncoder collectionType, List<String> values, Throwable cause) {
+    super(values + " cannot be encoded as " + collectionType.name(), cause);
+    this.collectionType = collectionType;
+    this.values = ImmutableList.copyOf(values);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterValueException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterValueException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterValueException.java
new file mode 100644
index 0000000..49a59ee
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ParameterValueException.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+import static org.apache.lens.api.error.LensCommonErrorCode.INVALID_PARAMETER_VALUE;
+
+import java.util.List;
+
+import org.apache.lens.server.api.LensErrorInfo;
+import org.apache.lens.server.api.error.LensException;
+
+import com.google.common.collect.ImmutableList;
+import lombok.Getter;
+
+/**
+ * The class ParameterValueException.
+ * Thrown when there is an exception encoding the value for a parameter.
+ */
+public class ParameterValueException extends LensException {
+  @Getter
+  private final String paramName;
+  @Getter
+  private final ImmutableList<String> values;
+
+  public ParameterValueException(String paramName, List<String> values, Throwable cause) {
+    super(
+      new LensErrorInfo(INVALID_PARAMETER_VALUE.getValue(), 0, INVALID_PARAMETER_VALUE.toString())
+      , values
+      , paramName
+      , cause.getMessage());
+    this.paramName = paramName;
+    this.values = ImmutableList.copyOf(values);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/PrivilegeException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/PrivilegeException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/PrivilegeException.java
new file mode 100644
index 0000000..0d85b8c
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/PrivilegeException.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+import static org.apache.lens.api.error.LensCommonErrorCode.NOT_AUTHORIZED;
+
+import org.apache.lens.server.api.LensErrorInfo;
+import org.apache.lens.server.api.error.LensException;
+
+import lombok.Getter;
+
+/**
+ * The class PrivilegeException. Thrown when the user is
+ * not having the required privileges to complete the action.
+ */
+public class PrivilegeException extends LensException {
+
+  @Getter
+  private final String resourceType;
+  @Getter
+  private final String resourceIdentifier;
+  @Getter
+  private final String privilege;
+
+  public PrivilegeException(String resourceType, String resourceIdentifier, String privilege) {
+    super(
+      new LensErrorInfo(NOT_AUTHORIZED.getValue(), 0, NOT_AUTHORIZED.toString())
+      , privilege
+      , resourceType
+      , resourceIdentifier);
+    this.resourceType = resourceType;
+    this.resourceIdentifier = resourceIdentifier;
+    this.privilege = privilege;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/SavedQueryNotFound.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/SavedQueryNotFound.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/SavedQueryNotFound.java
new file mode 100644
index 0000000..1c5acf8
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/SavedQueryNotFound.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+import static org.apache.lens.api.error.LensCommonErrorCode.RESOURCE_NOT_FOUND;
+
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.LensErrorInfo;
+import org.apache.lens.server.api.error.LensException;
+
+import lombok.Getter;
+
+/**
+ * The class SavedQueryNotFound.
+ * Thrown when the requested saved query is not found.
+ */
+public class SavedQueryNotFound extends LensException {
+
+  @Getter
+  private long id;
+
+  public SavedQueryNotFound(long id) {
+    super(
+      new LensErrorInfo(RESOURCE_NOT_FOUND.getValue(), 0, RESOURCE_NOT_FOUND.toString())
+      , SavedQuery.class.getSimpleName()
+      , String.valueOf(id));
+    this.id = id;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ValueEncodeException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ValueEncodeException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ValueEncodeException.java
new file mode 100644
index 0000000..d17e26f
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/exception/ValueEncodeException.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.exception;
+
+
+import org.apache.lens.api.query.save.ParameterDataType;
+import org.apache.lens.server.api.error.LensException;
+
+import lombok.Getter;
+
+/**
+ * The class ValueEncodeException.
+ * Thrown when the value cannot be encoded according to the data type specified in the definition.
+ */
+public class ValueEncodeException extends LensException {
+  @Getter
+  private final ParameterDataType dataType;
+  @Getter
+  private final Object valueSupplied;
+
+  public ValueEncodeException(ParameterDataType dataType, Object valueSupplied, Throwable cause) {
+    super(valueSupplied + " cannot be encoded as " + dataType.name(), cause);
+    this.dataType = dataType;
+    this.valueSupplied = valueSupplied;
+  }
+
+  public ValueEncodeException(ParameterDataType dataType, Object valueSupplied) {
+    super(valueSupplied + " cannot be encoded as " + dataType.name());
+    this.dataType = dataType;
+    this.valueSupplied = valueSupplied;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterCollectionTypeEncoder.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterCollectionTypeEncoder.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterCollectionTypeEncoder.java
new file mode 100644
index 0000000..7992eb5
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterCollectionTypeEncoder.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.param;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.lens.api.query.save.ParameterDataType;
+import org.apache.lens.server.api.query.save.exception.ParameterCollectionException;
+import org.apache.lens.server.api.query.save.exception.ValueEncodeException;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+
+/**
+ * The enum ParameterCollectionTypeEncoder.
+ * Encoder for encoding the value according to the collection type.
+ */
+@XmlRootElement
+public enum ParameterCollectionTypeEncoder {
+  SINGLE {
+    @Override
+    public String encode(ParameterDataType dataType, List<String> values)
+      throws ValueEncodeException, ParameterCollectionException {
+      if (values.size() != 1) {
+        throw new ParameterCollectionException(this, values, "Has to be exactly one");
+      }
+      return ParameterDataTypeEncoder.encodeFor(dataType, values.get(0));
+    }
+  },
+  MULTIPLE {
+    @Override
+    public String encode(final ParameterDataType dataType, List<String> values)
+      throws ValueEncodeException, ParameterCollectionException {
+      if (values.size() <= 0) {
+        throw new ParameterCollectionException(this, values, "Need atleast one value");
+      }
+      final StringBuilder builder = new StringBuilder("(");
+      List<String> transformedValues = Lists.newArrayList();
+      for (String rawValue : values) {
+        transformedValues.add(ParameterDataTypeEncoder.encodeFor(dataType, rawValue));
+      }
+      Joiner.on(',').skipNulls().appendTo(
+        builder,
+        transformedValues
+      );
+      return builder.append(")").toString();
+    }
+  };
+
+  public abstract String encode(ParameterDataType dataType, List<String> value) throws
+    ValueEncodeException, ParameterCollectionException;
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterDataTypeEncoder.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterDataTypeEncoder.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterDataTypeEncoder.java
new file mode 100644
index 0000000..5295f68
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterDataTypeEncoder.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.param;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.lens.api.query.save.ParameterDataType;
+import org.apache.lens.server.api.query.save.exception.ValueEncodeException;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+
+/**
+ * The enum ParameterDataTypeEncoder.
+ * Encodes the value according to the data type.
+ *
+ */
+@XmlRootElement
+public enum ParameterDataTypeEncoder {
+  STRING {
+    public String encode(String rawValue) {
+      return "'" + StringEscapeUtils.escapeEcmaScript(rawValue) + "'";
+    }
+
+    @Override
+    public String getSampleValue() {
+      return "sample_string_val";
+    }
+  },
+  NUMBER {
+    public String encode(String rawValue) {
+      return String.valueOf(Long.parseLong(rawValue));
+    }
+
+    @Override
+    public String getSampleValue() {
+      return String.valueOf(Long.MAX_VALUE);
+    }
+  },
+  DECIMAL {
+    public String encode(String rawValue) {
+      return String.valueOf(Double.parseDouble(rawValue));
+    }
+
+    @Override
+    public String getSampleValue() {
+      return String.valueOf(Double.MAX_VALUE);
+    }
+  },
+  BOOLEAN {
+    @Override
+    public String encode(String rawValue) {
+      if (rawValue.equalsIgnoreCase("true") || rawValue.equalsIgnoreCase("false")) {
+        return rawValue;
+      }
+      throw new RuntimeException("boolean has to be strictly true or false");
+    }
+
+    @Override
+    public String getSampleValue() {
+      return Boolean.TRUE.toString();
+    }
+  };
+
+  public abstract String encode(String rawValue);
+  public abstract String getSampleValue();
+
+  public static String encodeFor(ParameterDataType dataType, String rawValue) throws ValueEncodeException {
+    try {
+      return ParameterDataTypeEncoder.valueOf(dataType.toString()).encode(rawValue);
+    } catch (Throwable e) {
+      throw new ValueEncodeException(dataType, rawValue , e);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterParser.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterParser.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterParser.java
new file mode 100644
index 0000000..7364a2b
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterParser.java
@@ -0,0 +1,135 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.param;
+
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.lens.api.query.save.Parameter;
+import org.apache.lens.api.query.save.ParameterParserResponse;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Responsible for parsing the query (any grammar) and extracting parameters out of it
+ */
+public class ParameterParser {
+
+  private static final String PARAMETER_INDICATOR_PREFIX = ":";
+  private static final String SINGLE_QUOTED_LITERAL_PATTERN = "'[^']*'";
+  private static final String DOUBLE_QUOTED_LITERAL_PATTERN = "\"[^\"]*\"";
+  private static final Pattern PARAM_PATTERN = Pattern.compile(getPatternStringFor("[a-zA-Z][a-zA-Z1-9_]*"));
+
+  /**
+   *
+   * @param baseParameterPattern, regex denoting the parameters to match
+   * @return a regex pattern that captures the valid occurrences in the 1st group while
+   * ignoring occurrences inside literals (single/double quoted)
+   *
+   * To search for a parameter named p1, we will have to search for ':p1' that
+   * occurs natively in the query ignoring the ones that are single/double quoted.
+   * For eg. In the string - "Hai this is valid param :p1 and 'this is invalid param :p1'", the
+   * first occurrence is valid and the second is invalid as it falls under matching single quotes
+   *
+   * invalid_pattern_1|invalid_pattern_2|PARAMETER_INDICATOR_PREFIX(baseParameterPattern)
+   *
+   * For a baseParameterPattern - param1, the resulting pattern would be
+   * '[^']*'|"[^"]*"|:(param1)
+   */
+  public static String getPatternStringFor(String baseParameterPattern) {
+    final StringBuilder patternBuilder = new StringBuilder();
+    Joiner.on("|").appendTo(patternBuilder, getInvalidPatterns());
+    patternBuilder.append("|");
+    patternBuilder.append(PARAMETER_INDICATOR_PREFIX);
+    patternBuilder.append("(");
+    patternBuilder.append(baseParameterPattern);
+    patternBuilder.append(")");
+    return patternBuilder.toString();
+  }
+
+  /**
+   *
+   * @return a list of invalid regexp patterns that could possibly contain the parameter.
+   */
+  private static List<String> getInvalidPatterns() {
+    final List<String> invalidPatternList = Lists.newArrayList();
+    invalidPatternList.add(SINGLE_QUOTED_LITERAL_PATTERN);
+    invalidPatternList.add(DOUBLE_QUOTED_LITERAL_PATTERN);
+    return invalidPatternList;
+  }
+
+  /**
+   * Returns the length of the parameter prefix configured.
+   *
+   * @return length of the parameter prefix
+   */
+  public static int getParameterPrefixLength() {
+    return PARAMETER_INDICATOR_PREFIX.length();
+  }
+
+  private final String query;
+
+  public ParameterParser(String query) {
+    this.query = query;
+  }
+
+  /**
+   * Returns set of parameter names found in the query
+   *
+   * @return set of parameter names
+   */
+  public Set<String> extractParameterNames() {
+    final ParameterParserResponse parameterParserResponse = extractParameters();
+    return Sets.newHashSet(
+      Collections2.transform(parameterParserResponse.getParameters(), new Function<Parameter, String>() {
+        @Override
+        public String apply(Parameter parameter) {
+          return parameter.getName();
+        }
+      }));
+  }
+
+  /**
+   * Returns parameter parser response for the query
+   *
+   * @return ParameterParserResponse object
+   */
+  public ParameterParserResponse extractParameters() {
+    final Matcher m = PARAM_PATTERN.matcher(query);
+    final Set<Parameter> allParams = Sets.newHashSet();
+    while (m.find()) {
+      String validMatch = m.group(1);
+      if (validMatch != null) {
+        allParams.add(new Parameter(validMatch));
+      }
+    }
+    return new ParameterParserResponse(
+      true,
+      null,
+      ImmutableSet.copyOf(allParams)
+    );
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterResolver.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterResolver.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterResolver.java
new file mode 100644
index 0000000..b7a9841
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/save/param/ParameterResolver.java
@@ -0,0 +1,126 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save.param;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.Parameter;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.query.save.SavedQueryHelper;
+import org.apache.lens.server.api.query.save.exception.MissingParameterException;
+import org.apache.lens.server.api.query.save.exception.ParameterCollectionException;
+import org.apache.lens.server.api.query.save.exception.ParameterValueException;
+import org.apache.lens.server.api.query.save.exception.ValueEncodeException;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+/**
+ * The class ParameterResolver.
+ * Takes care of resolving the parameter with values specified for the given query
+ *
+ */
+public class ParameterResolver {
+
+  private final ImmutableMap<String, Parameter> parameterMap;
+  private final SavedQuery savedQuery;
+  private final MultivaluedMap<String, String> queryParameters;
+
+  private ParameterResolver(SavedQuery savedQuery, MultivaluedMap<String, String> queryParameters) {
+    final ImmutableMap.Builder<String, Parameter> builder = ImmutableMap.builder();
+    for (Parameter parameter : savedQuery.getParameters()) {
+      builder.put(parameter.getName(), parameter);
+    }
+    parameterMap = builder.build();
+    this.savedQuery = savedQuery;
+    this.queryParameters = SavedQueryHelper.getDefaultParameterValues(savedQuery);
+    this.queryParameters.putAll(queryParameters);
+  }
+
+  /**
+   *
+   * @return resolved query
+   * @throws ParameterValueException, IllegalArgumentException
+   *
+   * The function resolves the provided values for the bind params.
+   * A MissingParameterException is thrown if a value is not provided for one of the params
+   *
+   */
+  private String resolve() throws ParameterValueException, MissingParameterException {
+    final Sets.SetView<String> unProvidedParameters
+      = Sets.difference(parameterMap.keySet(), queryParameters.keySet());
+    if (unProvidedParameters.size() > 0) {
+      throw new MissingParameterException(unProvidedParameters);
+    }
+    final StringBuilder query = new StringBuilder(savedQuery.getQuery());
+    for (Map.Entry<String, List<String>> parameter : queryParameters.entrySet()) {
+      final String parameterName = parameter.getKey();
+      final List<String> values = parameter.getValue();
+      final Parameter parameterDetail = parameterMap.get(parameterName);
+      final String encodedValue;
+      try {
+        encodedValue = ParameterCollectionTypeEncoder
+          .valueOf(parameterDetail.getCollectionType().toString())
+          .encode(
+            parameterDetail.getDataType(),
+            values
+          );
+      } catch (ValueEncodeException | ParameterCollectionException e) {
+        throw new ParameterValueException(parameterName, values, e);
+      }
+      resolveParameter(query, parameterName, encodedValue);
+    }
+    return query.toString();
+  }
+
+  /**
+   * The function replaces all the occurrences of the specified bind parameter with the resolved value.
+   * There could be more than one occurrence of a particular bind param
+   *
+   * For eg. select * from table where col1 = :p1 and col2 = :p1. In this case all the valid occurrences
+   * of the bind param p1 will be replaced by the resolved value.
+   *
+   * @param query (gets mutated)
+   * @param parameter, the bind param
+   * @param resolvedValue, the value to be resolved
+   */
+  private static void resolveParameter(StringBuilder query, String parameter, String resolvedValue) {
+    final Pattern pattern = Pattern.compile(ParameterParser.getPatternStringFor(parameter));
+    Matcher matcher = pattern.matcher(query);
+    while (matcher.find()) {
+      if (matcher.group(1) != null) {
+        final MatchResult result = matcher.toMatchResult();
+        query
+          .replace(result.start(1) - ParameterParser.getParameterPrefixLength(), result.end(1), resolvedValue);
+        matcher = pattern.matcher(query);
+      }
+    }
+  }
+
+  public static String resolve(SavedQuery savedQuery, MultivaluedMap<String, String> queryParameters)
+    throws ParameterValueException, MissingParameterException {
+    return new ParameterResolver(savedQuery, queryParameters).resolve();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterParser.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterParser.java b/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterParser.java
new file mode 100644
index 0000000..c5c473b
--- /dev/null
+++ b/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterParser.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.lens.server.api.query.save.param.ParameterParser;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+public class TestParameterParser {
+
+  private static final ImmutableMap<String, Set<String>> QUERY_TEST_CASES;
+  static {
+    ImmutableMap.Builder<String, Set<String>> builder = ImmutableMap.builder();
+    builder.put(
+      "select col1 from table where col2 = :param",
+      Sets.newHashSet("param")
+    );
+    builder.put(
+      "select col1 from table where col2 in :param",
+      Sets.newHashSet("param")
+    );
+    builder.put(
+      "select col1 from table where col2 = 'a :param inside single quoted string literal'",
+      Sets.<String>newHashSet()
+    );
+    builder.put(
+      "select col1 from table where col2 = \"a :param inside double quoted string literal\"",
+      Sets.<String>newHashSet()
+    );
+    builder.put(
+      "select col1 from table where col1 = 'value' and col2 = :param and col3 = 'val3'",
+      Sets.newHashSet("param")
+    );
+    builder.put(
+      "select col1 from table where col1 = \"value\" and col2 = :param and col3 = \"val3\"",
+      Sets.newHashSet("param")
+    );
+
+
+    QUERY_TEST_CASES = builder.build();
+  }
+
+
+  @Test
+  public void testParsing() {
+    for(Map.Entry<String, Set<String>> testCase : QUERY_TEST_CASES.entrySet()) {
+      final String query = testCase.getKey();
+      Assert.assertEquals(
+        testCase.getValue(),
+        Sets.newHashSet(new ParameterParser(query).extractParameterNames()),
+        "Test case [[" + testCase.getKey() + "]] failed : "
+      );
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterResolution.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterResolution.java b/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterResolution.java
new file mode 100644
index 0000000..fae65cc
--- /dev/null
+++ b/lens-server-api/src/test/java/org/apache/lens/server/api/query/save/TestParameterResolution.java
@@ -0,0 +1,176 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.api.query.save;
+
+import static org.apache.lens.api.query.save.ParameterCollectionType.MULTIPLE;
+import static org.apache.lens.api.query.save.ParameterCollectionType.SINGLE;
+import static org.apache.lens.api.query.save.ParameterDataType.*;
+
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.Parameter;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.query.save.exception.MissingParameterException;
+import org.apache.lens.server.api.query.save.exception.ParameterValueException;
+import org.apache.lens.server.api.query.save.param.ParameterResolver;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Lists;
+
+public class TestParameterResolution {
+
+  private static final String QUERY_STRING = "select * from table where "
+    + "col = :param1 and "
+    + "col = :param1 and "
+    + "col = 'a :param1 inside single quotes' and "
+    + "col = \"a :param1 inside double quotes\" and "
+    + "col in :param2 and "
+    + "col = :param3 and "
+    + "col in :param4 and "
+    + "col = :param5 and "
+    + "col = :param7 and "
+    + "col in :param8 and "
+    + "col in :param6";
+
+  private static final SavedQuery QUERY = new SavedQuery(
+    1,
+    "query_name",
+    "description",
+    QUERY_STRING
+    ,
+    Lists.newArrayList(
+      new Parameter(
+        "param1", "Param1", new String[]{"val"}, STRING, SINGLE
+      ),
+      new Parameter(
+        "param2", "Param2", new String[]{"val1", "val2"}, STRING, MULTIPLE
+      ),
+      new Parameter(
+        "param3", "Param3", new String[]{"1"}, NUMBER, SINGLE
+      ),
+      new Parameter(
+        "param4", "Param4", new String[]{"1", "2"}, NUMBER, MULTIPLE
+      ),
+      new Parameter(
+        "param7", "Param7", new String[]{"1"}, DECIMAL, SINGLE
+      ),
+      new Parameter(
+        "param8", "Param8", new String[]{"1.2", "2.1"}, DECIMAL, MULTIPLE
+      ),
+      new Parameter(
+        "param5", "Param5", new String[]{"true"}, BOOLEAN, SINGLE
+      ),
+      new Parameter(
+        "param6", "Param6", null, BOOLEAN, MULTIPLE
+      )
+    )
+  );
+
+
+  @Test
+  public void testWithProperValues() throws ParameterValueException, MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param6", Lists.newArrayList("true", "false"));
+    String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+    Assert.assertEquals(
+      "select * from table where col = 'val' and col = 'val' and col = 'a :param1 inside single quotes' "
+        + "and col = \"a :param1 inside double quotes\" and col in ('val1','val2') and col = 1 and col in (1,2) "
+        + "and col = true and col = 1.0 and col in (1.2,2.1) and col in (true,false)",
+      resolvedQuery,
+      "Query resolution did not happen correctly"
+    );
+  }
+
+  @Test
+  public void testWithInvalidValueForNumber() throws MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param3", Lists.newArrayList("number"));
+    parameterValues.put("param6", Lists.newArrayList("true", "false"));
+    try {
+      final String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+      Assert.fail("The query seem to have resolved with invalid datatype : " + resolvedQuery);
+    } catch (ParameterValueException e) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testWithInvalidValueForBoolean() throws MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param5", Lists.newArrayList("boolean"));
+    parameterValues.put("param6", Lists.newArrayList("true", "false"));
+    try {
+      final String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+      Assert.fail("The query seem to have resolved with invalid datatype : " + resolvedQuery);
+    } catch (ParameterValueException e) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testWithInvalidValueForDecimal() throws MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param7", Lists.newArrayList("decimal"));
+    parameterValues.put("param6", Lists.newArrayList("true", "false"));
+    try {
+      final String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+      Assert.fail("The query seem to have resolved with invalid datatype : " + resolvedQuery);
+    } catch (ParameterValueException e) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testWithIncorrectCollectionTypeForSingle() throws MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param5", Lists.newArrayList("true", "false"));
+    parameterValues.put("param6", Lists.newArrayList("true"));
+    try {
+      final String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+      Assert.fail("The query seem to have resolved with invalid collection type : " + resolvedQuery);
+    } catch (ParameterValueException e) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testWithIncorrectCollectionTypeForMultiple() throws MissingParameterException {
+    MultivaluedMap<String, String> parameterValues = new MultivaluedHashMap<>();
+    parameterValues.put("param6", Lists.<String>newArrayList());
+    try {
+      final String resolvedQuery = ParameterResolver.resolve(QUERY, parameterValues);
+      Assert.fail("The query seem to have resolved with invalid collection type : " + resolvedQuery);
+    } catch (ParameterValueException e) {
+      Assert.assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testWithMissingParameters() throws ParameterValueException{
+    try {
+      String resolvedQuery = ParameterResolver.resolve(QUERY, new MultivaluedHashMap<String, String>());
+      Assert.fail("The query seem to have resolved with missing parameters : " + resolvedQuery);
+    } catch (MissingParameterException e) {
+      Assert.assertTrue(true);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/enunciate.xml
----------------------------------------------------------------------
diff --git a/lens-server/enunciate.xml b/lens-server/enunciate.xml
index 94b5199..7013f13 100644
--- a/lens-server/enunciate.xml
+++ b/lens-server/enunciate.xml
@@ -31,6 +31,7 @@
   </services>
   <api-classes>
     <include pattern="org.apache.lens.server.query.*"/>
+    <include pattern="org.apache.lens.server.query.save.*"/>
     <include pattern="org.apache.lens.server.metastore.*"/>
     <include pattern="org.apache.lens.server.quota.*"/>
     <include pattern="org.apache.lens.server.scheduler.*"/>

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryApp.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryApp.java b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryApp.java
new file mode 100644
index 0000000..e55ed13
--- /dev/null
+++ b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryApp.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.save;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+import org.apache.lens.server.LensApplicationListener;
+import org.apache.lens.server.LensRequestContextInitFilter;
+
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+
+/**
+ * The Class SavedQueryApp.
+ */
+@ApplicationPath("/savedquery")
+public class SavedQueryApp extends Application {
+  @Override
+  public Set<Class<?>> getClasses() {
+    final Set<Class<?>> classes = new HashSet<Class<?>>();
+    classes.add(SavedQueryResource.class);
+    classes.add(MultiPartFeature.class);
+    classes.add(LensRequestContextInitFilter.class);
+    classes.add(LoggingFilter.class);
+    classes.add(LensApplicationListener.class);
+    return classes;
+  }
+}


[19/50] [abbrv] lens git commit: LENS-742 : Adds query feature : Saved query and parameterization

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryDao.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryDao.java b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryDao.java
new file mode 100644
index 0000000..9dfde0d
--- /dev/null
+++ b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryDao.java
@@ -0,0 +1,483 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.save;
+
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.ListResponse;
+import org.apache.lens.api.query.save.Parameter;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.save.exception.SavedQueryNotFound;
+
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.commons.dbutils.ResultSetHandler;
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+public class SavedQueryDao {
+
+  private static final ObjectMapper MAPPER = new ObjectMapper();
+  private static final String VALUE_ALIAS = "value_alias";
+  private static final String SAVED_QUERY_TABLE_NAME = "saved_query";
+  private static final String ID_COL_NAME = "id";
+  private static final String NAME_COL_NAME = "name";
+  private static final String DESCRIPTION_COL_NAME = "description";
+  private static final String QUERY_COL_NAME = "query";
+  private static final String PARAMS_COL_NAME = "params_json";
+  private static final String CREATED_AT_COL_NAME = "created_at";
+  private static final String UPDATED_AT_COL_NAME = "updated_at";
+
+  private final QueryRunner runner;
+  private final Dialect dialect;
+
+  SavedQueryDao(String dialectClass, QueryRunner runner)
+    throws LensException {
+    try {
+      this.runner = runner;
+      this.dialect = (Dialect) Class.forName(dialectClass).newInstance();
+      createSavedQueryTableIfNotExists();
+    } catch (Exception e) {
+      throw new LensException("Error initializing saved query dao", e);
+    }
+  }
+
+  /**
+   * Creates the saved query table
+   *
+   * @throws LensException
+   */
+  public void createSavedQueryTableIfNotExists() throws LensException {
+    try {
+      runner.update(dialect.getCreateTableSyntax());
+    } catch (SQLException e) {
+      throw new LensException("Cannot create saved query table!", e);
+    }
+  }
+
+  /**
+   * Saves the query passed
+   *
+   * @param savedQuery
+   * @return
+   * @throws LensException
+   */
+  public long saveQuery(SavedQuery savedQuery) throws LensException {
+    try {
+      final ECMAEscapedSavedQuery ecmaEscaped = ECMAEscapedSavedQuery.getFor(savedQuery);
+      runner.update(
+        "insert into " + SAVED_QUERY_TABLE_NAME + " values (" + dialect.getAutoIncrementId(runner) + ", "
+          + "'" + ecmaEscaped.getName() + "'"
+          + ", "
+          + "'" + ecmaEscaped.getDescription() + "'"
+          + ","
+          + "'" + ecmaEscaped.getQuery() + "'"
+          + ","
+          + "'" + ecmaEscaped.getParameters() + "'"
+          + ","
+          + "now()"
+          + ","
+          + "now()"
+          + ")"
+      );
+      return dialect.getLastInsertedID(runner);
+    } catch (SQLException e) {
+      throw new LensException("Save query failed !", e);
+    }
+  }
+
+  /**
+   * Updates the saved query id with new payload
+   *
+   * @param id
+   * @param savedQuery
+   * @throws LensException
+   */
+  public void updateQuery(long id, SavedQuery savedQuery) throws LensException {
+    try {
+      final ECMAEscapedSavedQuery ecmaEscaped = ECMAEscapedSavedQuery.getFor(savedQuery);
+      final int rowsUpdated = runner.update(
+        "update " + SAVED_QUERY_TABLE_NAME +"  set "
+          + NAME_COL_NAME + " = '" + ecmaEscaped.getName() + "',"
+          + DESCRIPTION_COL_NAME + " = '" + ecmaEscaped.getDescription() + "',"
+          + QUERY_COL_NAME + " = '" + ecmaEscaped.getQuery() + "',"
+          + PARAMS_COL_NAME + " = '" + ecmaEscaped.getParameters() + "',"
+          + UPDATED_AT_COL_NAME + " = now() "
+          + "where " + ID_COL_NAME + " = " + id
+      );
+      if (rowsUpdated == 0) {
+        throw new SavedQueryNotFound(id);
+      }
+    } catch (SQLException e) {
+      throw new LensException("Update failed for " + id, e);
+    }
+  }
+
+  /**
+   * Gets saved query with the given id
+   *
+   * @param id
+   * @return
+   * @throws LensException
+   */
+  public SavedQuery getSavedQueryByID(long id) throws LensException {
+    final List<SavedQuery> savedQueries;
+    try {
+      savedQueries = runner.query(
+        "select * from " + SAVED_QUERY_TABLE_NAME + " where " + ID_COL_NAME + " = " + id,
+        new SavedQueryResultSetHandler()
+      );
+    } catch (SQLException e) {
+      throw new LensException("Get failed for " + id, e);
+    }
+    int size = savedQueries.size();
+    switch (size) {
+    case 0:
+      throw new SavedQueryNotFound(id);
+    case 1:
+      return savedQueries.get(0);
+    default:
+      throw new RuntimeException("More than one obtained for id, Please check the integrity of the data!");
+    }
+  }
+
+  /**
+   * Returns a list of saved queries
+   *
+   * @param criteria  a multivalued map that has the filter criteria
+   * @param start     Displacement from the start of the search result
+   * @param count     Count of number of records required
+   * @return list of saved queries
+   * @throws LensException
+   */
+  public ListResponse getList(
+    MultivaluedMap<String, String> criteria, long start, long count) throws LensException {
+    final StringBuilder selectQueryBuilder = new StringBuilder("select * from " + SAVED_QUERY_TABLE_NAME);
+    final Set<String> availableFilterKeys = FILTER_KEYS.keySet();
+    final Sets.SetView<String> intersection = Sets.intersection(availableFilterKeys, criteria.keySet());
+    if (intersection.size() > 0) {
+      final StringBuilder whereClauseBuilder = new StringBuilder(" where ");
+      final List<String> predicates = Lists.newArrayList();
+      for (String colName : intersection) {
+        predicates.add(
+          FILTER_KEYS.get(colName)
+            .resolveFilterExpression(
+              colName,
+              criteria.getFirst(colName)
+            )
+        );
+      }
+      Joiner.on(" and ").skipNulls().appendTo(whereClauseBuilder, predicates);
+      selectQueryBuilder.append(whereClauseBuilder.toString());
+    }
+    final String listCountQuery = "select count(*) as " + VALUE_ALIAS
+      + " from (" + selectQueryBuilder.toString() + ") tmp_table";
+    selectQueryBuilder
+      .append(" limit ")
+      .append(start)
+      .append(", ")
+      .append(count);
+    final String listQuery = selectQueryBuilder.toString();
+    try {
+      return new ListResponse(
+        start,
+        runner.query(listCountQuery, new SingleValuedResultHandler()),
+        runner.query(listQuery, new SavedQueryResultSetHandler())
+      );
+    } catch (SQLException e) {
+      throw new LensException("List query failed!", e);
+    }
+  }
+
+  /**
+   * Deletes the saved query with the given id
+   *
+   * @param id
+   * @throws LensException
+   */
+  public void deleteSavedQueryByID(long id) throws LensException {
+    try {
+      int rowsDeleted = runner.update(
+        "delete from " + SAVED_QUERY_TABLE_NAME +" where " + ID_COL_NAME + " = " + id
+      );
+      if (rowsDeleted == 0) {
+        throw new SavedQueryNotFound(id);
+      } else if (rowsDeleted > 1) {
+        throw new LensException("Warning! More than one record was deleted", new Throwable());
+      }
+    } catch (SQLException e) {
+      throw new LensException("Delete query failed", e);
+    }
+  }
+
+  /**
+   * The interface Dialect.
+   */
+  public interface Dialect {
+    /**
+     * The create table syntax for 'this' dialect
+     * @return
+     */
+    String getCreateTableSyntax();
+
+    /**
+     * Method to get the auto increment id/keyword(null) for the ID column
+     * @param runner
+     * @return
+     * @throws SQLException
+     */
+    Long getAutoIncrementId(QueryRunner runner)  throws SQLException;
+
+    /**
+     * Get the last increment id after doing an auto increment
+     * @param runner
+     * @return
+     * @throws SQLException
+     */
+    Long getLastInsertedID(QueryRunner runner) throws SQLException;
+  }
+
+  /**
+   * MySQL dialect for saved query.
+   */
+  public static class MySQLDialect implements Dialect {
+
+    @Override
+    public String getCreateTableSyntax() {
+      return "CREATE TABLE IF NOT EXISTS " + SAVED_QUERY_TABLE_NAME + " ("
+        + ID_COL_NAME + " int(11) NOT NULL AUTO_INCREMENT,"
+        + NAME_COL_NAME + " varchar(255) NOT NULL,"
+        + DESCRIPTION_COL_NAME + " varchar(255) DEFAULT NULL,"
+        + QUERY_COL_NAME + " longtext,"
+        + PARAMS_COL_NAME + " longtext,"
+        + CREATED_AT_COL_NAME + " timestamp,"
+        + UPDATED_AT_COL_NAME + " timestamp,"
+        + "  PRIMARY KEY ("+ ID_COL_NAME +")"
+        + ")";
+
+    }
+
+    @Override
+    public Long getAutoIncrementId(QueryRunner runner) throws SQLException {
+      return null;
+    }
+
+    @Override
+    public Long getLastInsertedID(QueryRunner runner) throws SQLException {
+      return runner.query(
+        "select last_insert_id() as " + VALUE_ALIAS,
+        new SingleValuedResultHandler()
+      );
+    }
+  }
+
+  /**
+   * HSQL dialect for saved query (Used with testing).
+   */
+  public static class HSQLDialect implements Dialect {
+
+    @Override
+    public String getCreateTableSyntax() {
+      return "CREATE TABLE if not exists " + SAVED_QUERY_TABLE_NAME + "  ("
+        + ID_COL_NAME + " int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "
+        + NAME_COL_NAME + " varchar(255), "
+        + DESCRIPTION_COL_NAME + " varchar(255), "
+        + QUERY_COL_NAME + " varchar(255), "
+        + PARAMS_COL_NAME + " varchar(255), "
+        + CREATED_AT_COL_NAME + " timestamp, "
+        + UPDATED_AT_COL_NAME + " timestamp)";
+
+    }
+
+    @Override
+    public Long getAutoIncrementId(QueryRunner runner) throws SQLException {
+      return runner.query("select max(" + ID_COL_NAME + ")  as " + VALUE_ALIAS +" from " + SAVED_QUERY_TABLE_NAME
+        , new SingleValuedResultHandler()) + 1;
+    }
+
+    @Override
+    public Long getLastInsertedID(QueryRunner runner) throws SQLException {
+      Long id = runner.query("select max(" + ID_COL_NAME + ")  as " + VALUE_ALIAS + " from " + SAVED_QUERY_TABLE_NAME
+        , new SingleValuedResultHandler());
+      if (id == 0) {
+        id++;
+      }
+      return id;
+    }
+  }
+
+  /**
+   * Result set handler class to get a saved query from result set
+   */
+  public static class SavedQueryResultSetHandler implements ResultSetHandler<List<SavedQuery>> {
+
+    @Override
+    public List<SavedQuery> handle(ResultSet resultSet) throws SQLException {
+      List<SavedQuery> queries = Lists.newArrayList();
+      while (resultSet.next()) {
+        long id = resultSet.getLong(ID_COL_NAME);
+        final String name = StringEscapeUtils.unescapeEcmaScript(resultSet.getString(NAME_COL_NAME));
+        final String description = StringEscapeUtils.unescapeEcmaScript(resultSet.getString(DESCRIPTION_COL_NAME));
+        final String query = StringEscapeUtils.unescapeEcmaScript(resultSet.getString(QUERY_COL_NAME));
+        final List<Parameter> parameterList;
+        try {
+          parameterList = deserializeFrom(
+            StringEscapeUtils.unescapeEcmaScript(resultSet.getString(PARAMS_COL_NAME))
+          );
+        } catch (LensException e) {
+          throw new SQLException("Cannot deserialize parameters ", e);
+        }
+        queries.add(new SavedQuery(
+          id,
+          name,
+          description,
+          query,
+          parameterList
+        ));
+      }
+      return queries;
+    }
+  }
+
+  /**
+   * Result set handler class to get a the last inserted ID from the resultset
+   */
+  public static class SingleValuedResultHandler implements ResultSetHandler<Long> {
+
+    @Override
+    public Long handle(ResultSet resultSet) throws SQLException {
+      while (resultSet.next()) {
+        return resultSet.getLong(VALUE_ALIAS);
+      }
+      throw new SQLException("For cursor : " + resultSet.getCursorName());
+    }
+  }
+
+  @AllArgsConstructor
+  @Data
+  /**
+   * This class represents a ECMA escaped version of saved query,
+   * that can be safely inserted into DB
+   */
+  private static class ECMAEscapedSavedQuery {
+    private final long id;
+    private final String name;
+    private final String description;
+    private final String query;
+    private final String parameters;
+
+    static ECMAEscapedSavedQuery getFor(SavedQuery savedQuery) throws LensException {
+      return new ECMAEscapedSavedQuery(
+        savedQuery.getId(),
+        StringEscapeUtils.escapeEcmaScript(savedQuery.getName()),
+        StringEscapeUtils.escapeEcmaScript(savedQuery.getDescription()),
+        StringEscapeUtils.escapeEcmaScript(savedQuery.getQuery()),
+        StringEscapeUtils.escapeEcmaScript(serializeParameters(savedQuery))
+      );
+    }
+  }
+
+  /**
+   * The filter data type used in the list api
+   */
+  enum FilterDataType {
+    STRING {
+      String resolveFilterExpression(String col, String val) {
+        return " " + col + " like '%" + val + "%'";
+      }
+    },
+    NUMBER {
+      String resolveFilterExpression(String col, String val) {
+        return col + "=" + Long.parseLong(val);
+      }
+    },
+    BOOLEAN {
+      String resolveFilterExpression(String col, String val) {
+        return col + "=" + Boolean.parseBoolean(val);
+      }
+    };
+
+    abstract String resolveFilterExpression(String col, String val);
+  }
+
+  /**
+   * Map of available filter keys and their data types
+   * The list api can have filter criteria based on these keys.
+   */
+  private static final ImmutableMap<String, FilterDataType> FILTER_KEYS;
+
+  static {
+    final ImmutableMap.Builder<String, FilterDataType> filterValuesBuilder = ImmutableMap.builder();
+    filterValuesBuilder.put(NAME_COL_NAME, FilterDataType.STRING);
+    filterValuesBuilder.put(DESCRIPTION_COL_NAME, FilterDataType.STRING);
+    filterValuesBuilder.put(QUERY_COL_NAME, FilterDataType.STRING);
+    filterValuesBuilder.put(ID_COL_NAME, FilterDataType.NUMBER);
+    FILTER_KEYS = filterValuesBuilder.build();
+  }
+
+
+  /**
+   * Serializes the parameters of saved query using jackson
+   *
+   * @param savedQuery
+   * @return
+   * @throws LensException
+   */
+  private static String serializeParameters(SavedQuery savedQuery) throws LensException {
+    final String paramsJson;
+    try {
+      paramsJson = MAPPER.writeValueAsString(savedQuery.getParameters());
+    } catch (JsonProcessingException e) {
+      throw new LensException("Serialization failed for " + savedQuery.getParameters(), e);
+    }
+    return paramsJson;
+  }
+
+  /**
+   * Deserializes the parameters from string using jackson
+   *
+   * @param paramsJson
+   * @return
+   * @throws LensException
+   */
+  private static List<Parameter> deserializeFrom(String paramsJson) throws LensException {
+    final Parameter[] parameterArray;
+    try {
+      parameterArray = MAPPER.readValue(paramsJson, Parameter[].class);
+    } catch (IOException e) {
+      throw new LensException("Failed to deserialize from " + paramsJson, e);
+    }
+    return Arrays.asList(parameterArray);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryResource.java b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryResource.java
new file mode 100644
index 0000000..a7e0aef
--- /dev/null
+++ b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryResource.java
@@ -0,0 +1,307 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.save;
+
+import static org.apache.lens.api.error.LensCommonErrorCode.INVALID_XML_ERROR;
+import static org.apache.lens.api.query.save.ResourceModifiedResponse.Action.CREATED;
+import static org.apache.lens.api.query.save.ResourceModifiedResponse.Action.DELETED;
+import static org.apache.lens.api.query.save.ResourceModifiedResponse.Action.UPDATED;
+import static org.apache.lens.server.api.LensConfConstants.*;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.lens.api.LensConf;
+import org.apache.lens.api.LensSessionHandle;
+import org.apache.lens.api.error.ErrorCollection;
+import org.apache.lens.api.query.QuerySubmitResult;
+import org.apache.lens.api.query.save.ListResponse;
+import org.apache.lens.api.query.save.ParameterParserResponse;
+import org.apache.lens.api.query.save.ResourceModifiedResponse;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.api.result.LensAPIResult;
+import org.apache.lens.cube.parse.HQLParser;
+import org.apache.lens.server.LensServices;
+import org.apache.lens.server.api.LensErrorInfo;
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.query.QueryExecutionService;
+import org.apache.lens.server.api.query.save.*;
+import org.apache.lens.server.api.query.save.param.ParameterParser;
+import org.apache.lens.server.api.query.save.param.ParameterResolver;
+import org.apache.lens.server.model.LogSegregationContext;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+
+import org.glassfish.grizzly.http.server.Response;
+import org.glassfish.jersey.media.multipart.FormDataParam;
+
+import lombok.NonNull;
+
+@Path("/queryapi")
+/**
+ * Saved query resource
+ * <p></p>
+ * CRUD on saved query
+ */
+public class SavedQueryResource {
+
+  final SavedQueryService savedQueryService;
+  final QueryExecutionService queryService;
+  private final ErrorCollection errorCollection;
+  private final LogSegregationContext logSegregationContext;
+  private static final String DEFAULT_START = "0";
+  private final int defaultCount;
+
+  public SavedQueryResource() {
+    savedQueryService = LensServices.get().getService(SavedQueryServiceImpl.NAME);
+    queryService = LensServices.get().getService(QueryExecutionService.NAME);
+    errorCollection = LensServices.get().getErrorCollection();
+    logSegregationContext = LensServices.get().getLogSegregationContext();
+    final HiveConf hiveConf = LensServices.get().getHiveConf();
+    defaultCount = hiveConf.getInt(FETCH_COUNT_SAVED_QUERY_LIST_KEY, DEFAULT_FETCH_COUNT_SAVED_QUERY_LIST);
+  }
+
+  @GET
+  @Path("/savedqueries/health")
+  @Produces(MediaType.TEXT_PLAIN)
+  /**
+   * Health check end point
+   */
+  public String getMessage() {
+    return "Saved query api is up";
+  }
+
+
+  /**
+   * Gets a list of saved queries matching the criteria (url parameters)
+   * windowed by count and start.
+   *
+   * @param sessionid  The sessionid in which user is working
+   * @param info       URI context injected for query parameters
+   * @param start      Offset to start from the search result
+   * @param count      Number of records to fetch from start
+   * @return {@link org.apache.lens.api.query.save.ListResponse} ListResponse object
+   * @throws LensException
+   */
+  @GET
+  @Path("/savedqueries")
+  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public ListResponse getList(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    @Context UriInfo info,
+    @DefaultValue(DEFAULT_START) @QueryParam("start") int start,
+    @QueryParam("count") String count) throws LensException {
+    try {
+      final int countVal = count == null? defaultCount: Integer.parseInt(count);
+      return savedQueryService.list(info.getQueryParameters(), start, countVal);
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Gets the saved query with the given id.
+   *
+   * @param sessionid  The sessionid in which user is working
+   * @param id         id of the saved query
+   * @return {@link org.apache.lens.api.query.save.SavedQuery} SavedQuery object
+   * @throws LensException
+   */
+  @GET
+  @Path("/savedqueries/{id}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public SavedQuery getByID(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    @PathParam("id") long id) throws LensException {
+    try {
+      return savedQueryService.get(id);
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Deletes the saved query with the given id.
+   *
+   * @param sessionid  The sessionid in which user is working
+   * @param id         id of the saved query
+   * @return {@link org.apache.lens.api.query.save.ResourceModifiedResponse} ResourceModifiedResponse object
+   * @throws LensException
+   */
+  @DELETE
+  @Path("/savedqueries/{id}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public ResourceModifiedResponse deleteById(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    @PathParam("id") long id) throws LensException {
+    try {
+      savedQueryService.delete(id);
+      return new ResourceModifiedResponse(id, "saved_query", DELETED);
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Creates a new saved query.
+   *
+   * @param sessionid   The sessionid in which user is working
+   * @param savedQuery  Saved query object
+   * @param response    Injected response context object
+   * @return {@link org.apache.lens.api.query.save.ResourceModifiedResponse} ResourceModifiedResponse object
+   * @throws LensException
+   * @throws IOException
+   */
+  @POST
+  @Path(("/savedqueries"))
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public ResourceModifiedResponse create(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    SavedQuery savedQuery,
+    @Context final Response response)
+    throws LensException, IOException {
+    try {
+      validateSampleResolved(savedQuery);
+      long id = savedQueryService.save(savedQuery);
+      response.setStatus(HttpServletResponse.SC_CREATED);
+      response.flush();
+      return new ResourceModifiedResponse(id, "saved_query", CREATED);
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Updates the saved query {id} with the new payload.
+   *
+   * @param sessionid   The sessionid in which user is working
+   * @param savedQuery  Saved query object
+   * @param response    Injected response context object
+   * @return {@link org.apache.lens.api.query.save.ResourceModifiedResponse} ResourceModifiedResponse object
+   * @throws LensException
+   * @throws IOException
+   */
+  @PUT
+  @Path("/savedqueries/{id}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public ResourceModifiedResponse update(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    @PathParam("id") long id,
+    SavedQuery savedQuery,
+    @Context final Response response) throws LensException, IOException {
+    try {
+      validateSampleResolved(savedQuery);
+      savedQueryService.update(id, savedQuery);
+      response.setStatus(HttpServletResponse.SC_CREATED);
+      response.flush();
+      return new ResourceModifiedResponse(id, "saved_query", UPDATED);
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Parses the query and returns parameters that are found in the query.
+   *
+   * @param sessionid  The sessionid in which user is working
+   * @param query      The HQL query
+   * @return {@link org.apache.lens.api.query.save.ParameterParserResponse} ParameterParserResponse object
+   */
+  @GET
+  @Path("/savedqueries/parameters")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+  public ParameterParserResponse getParameters(
+    @QueryParam("sessionid") LensSessionHandle sessionid,
+    @QueryParam("query") String query) {
+    return new ParameterParser(query).extractParameters();
+  }
+
+  /**
+   * Runs the saved query with the given id and returns a query handle.
+   *
+   * @param id         id of the saved query
+   * @param info       Injected UriInfo context object
+   * @param sessionid  The sessionid in which user is working
+   * @param conf       Lens configuration overrides for the query
+   * @return LensAPIResult containing the query handle
+   * @throws LensException
+   */
+  @POST
+  @Path("/savedqueries/{id}")
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
+  public LensAPIResult<? extends QuerySubmitResult> run(
+    @PathParam("id") long id,
+    @Context UriInfo info,
+    @FormDataParam("sessionid") LensSessionHandle sessionid,
+    @FormDataParam("conf") LensConf conf) throws LensException {
+    final String requestId = this.logSegregationContext.getLogSegragationId();
+    try {
+      final SavedQuery savedQuery = savedQueryService.get(id);
+      final String query = ParameterResolver.resolve(savedQuery, info.getQueryParameters());
+      return LensAPIResult.composedOf(
+        null,
+        requestId,
+        queryService.executeAsync(sessionid, query, conf, savedQuery.getName())
+      );
+    } catch (LensException e) {
+      throw getWrapped(e);
+    }
+  }
+
+  /**
+   * Helper method that builds error response for LensException provided.
+   *
+   * @param e    Lens exception object
+   * @return lens exception object with error response built
+   * @throws LensException
+   */
+  private LensException getWrapped(LensException e) throws
+    LensException {
+    e.buildLensErrorResponse(errorCollection, null, logSegregationContext.getLogSegragationId());
+    throw e;
+  }
+
+  /**
+   * Validates the saved query and throws LensException with.
+   * BAD_SYNTAX code if wrong
+   *
+   * @param savedQuery Saved query object
+   * @throws LensException if invalid
+   */
+  private void validateSampleResolved(@NonNull SavedQuery savedQuery) throws LensException {
+    final String sampleResolved  = SavedQueryHelper.getSampleResolvedQuery(savedQuery);
+    try {
+      HQLParser.parseHQL(sampleResolved, new HiveConf());
+    } catch (Exception e) {
+      throw new LensException(
+        new LensErrorInfo(INVALID_XML_ERROR.getValue(), 0, INVALID_XML_ERROR.toString())
+        , e
+        , "Encountered while resolving with sample values { " + sampleResolved + " }");
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryServiceImpl.java
new file mode 100644
index 0000000..d9de897
--- /dev/null
+++ b/lens-server/src/main/java/org/apache/lens/server/query/save/SavedQueryServiceImpl.java
@@ -0,0 +1,141 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.save;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.lens.api.query.save.ListResponse;
+import org.apache.lens.api.query.save.SavedQuery;
+import org.apache.lens.server.BaseLensService;
+import org.apache.lens.server.api.LensConfConstants;
+import org.apache.lens.server.api.error.LensException;
+import org.apache.lens.server.api.health.HealthStatus;
+import org.apache.lens.server.api.query.save.SavedQueryService;
+import org.apache.lens.server.util.UtilityMethods;
+
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hive.service.cli.CLIService;
+
+import lombok.NonNull;
+
+public class SavedQueryServiceImpl extends BaseLensService implements SavedQueryService {
+  private SavedQueryDao dao;
+  private Configuration conf;
+
+  public static final String NAME = "savedquery";
+
+  /**
+   * Instantiates a new lens service.
+   *
+   * @param cliService the cli service
+   */
+  public SavedQueryServiceImpl(CLIService cliService) throws LensException {
+    super(NAME, cliService);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public synchronized void init(HiveConf hiveConf) {
+    super.init(hiveConf);
+    conf = hiveConf;
+    @NonNull final String dialect = conf.get(LensConfConstants.JDBC_DIALECT_PROVIDER_CLASS_KEY
+      , SavedQueryDao.HSQLDialect.class.getCanonicalName());
+    try {
+      dao = new SavedQueryDao(
+        dialect,
+        new QueryRunner(UtilityMethods.getPoolingDataSourceFromConf(conf))
+      );
+    } catch (LensException e) {
+      throw new RuntimeException("Cannot initialize saved query service", e);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public HealthStatus getHealthStatus() {
+    return this.getServiceState().equals(STATE.STARTED)
+      ? new HealthStatus(true, "Saved query service is healthy.")
+      : new HealthStatus(false, "Saved query service is down.");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public long save(SavedQuery savedQuery) throws LensException {
+    return dao.saveQuery(savedQuery);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void update(long id, SavedQuery savedQuery) throws LensException {
+    dao.updateQuery(id, savedQuery);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void delete(long id) throws LensException {
+    dao.deleteSavedQueryByID(id);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public SavedQuery get(long id) throws LensException {
+    return dao.getSavedQueryByID(id);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ListResponse list(
+    MultivaluedMap<String, String> criteria, long start, long count) throws LensException {
+    return dao.getList(criteria, start, count);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void grant(long id, String sharingUser, String targetUserPath, String[] privileges)
+    throws LensException {
+    //NOOP
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void revoke(long id, String sharingUser, String targetUserPath, String[] privileges)
+    throws LensException {
+    //NOOP
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/java/org/apache/lens/server/util/UtilityMethods.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/util/UtilityMethods.java b/lens-server/src/main/java/org/apache/lens/server/util/UtilityMethods.java
index 5d77eb7..a6c7b13 100644
--- a/lens-server/src/main/java/org/apache/lens/server/util/UtilityMethods.java
+++ b/lens-server/src/main/java/org/apache/lens/server/util/UtilityMethods.java
@@ -29,9 +29,10 @@ import javax.sql.DataSource;
 
 import org.apache.lens.server.api.LensConfConstants;
 
-import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.dbcp.*;
 import org.apache.commons.dbutils.QueryRunner;
 import org.apache.commons.dbutils.ResultSetHandler;
+import org.apache.commons.pool.impl.GenericObjectPool;
 import org.apache.hadoop.conf.Configuration;
 
 
@@ -141,6 +142,22 @@ public final class UtilityMethods {
     return tmp;
   }
 
+  public static DataSource getPoolingDataSourceFromConf(Configuration conf) {
+    final ConnectionFactory cf = new DriverManagerConnectionFactory(
+      conf.get(LensConfConstants.SERVER_DB_JDBC_URL, LensConfConstants.DEFAULT_SERVER_DB_JDBC_URL),
+      conf.get(LensConfConstants.SERVER_DB_JDBC_USER, LensConfConstants.DEFAULT_SERVER_DB_USER),
+      conf.get(LensConfConstants.SERVER_DB_JDBC_PASS, LensConfConstants.DEFAULT_SERVER_DB_PASS));
+    final GenericObjectPool connectionPool = new GenericObjectPool();
+    connectionPool.setTestOnBorrow(false);
+    connectionPool.setTestOnReturn(false);
+    connectionPool.setTestWhileIdle(true);
+    new PoolableConnectionFactory(cf, connectionPool, null
+      , conf.get(LensConfConstants.SERVER_DB_VALIDATION_QUERY,
+        LensConfConstants.DEFAULT_SERVER_DB_VALIDATION_QUERY), false, false)
+      .setDefaultAutoCommit(true);
+    return new PoolingDataSource(connectionPool);
+  }
+
   /**
    * Conf to string.
    *

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/main/resources/lensserver-default.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/main/resources/lensserver-default.xml b/lens-server/src/main/resources/lensserver-default.xml
index 5d33eda..6a1ac7f 100644
--- a/lens-server/src/main/resources/lensserver-default.xml
+++ b/lens-server/src/main/resources/lensserver-default.xml
@@ -55,7 +55,7 @@
 
   <property>
     <name>lens.server.servicenames</name>
-    <value>session,query,metastore,scheduler,quota</value>
+    <value>session,query,metastore,scheduler,quota,savedquery</value>
     <description>These services would be started in the specified order when lens-server starts up</description>
   </property>
 
@@ -72,6 +72,12 @@
   </property>
 
   <property>
+    <name>lens.server.savedquery.service.impl</name>
+    <value>org.apache.lens.server.query.save.SavedQueryServiceImpl</value>
+    <description>Implementation class for saved query service</description>
+  </property>
+
+  <property>
     <name>lens.server.quota.service.impl</name>
     <value>org.apache.lens.server.quota.QuotaServiceImpl</value>
     <description>Implementation class for quota service</description>
@@ -360,7 +366,7 @@
 
   <property>
     <name>lens.server.ws.resourcenames</name>
-    <value>session,metastore,query,quota,scheduler,index,log</value>
+    <value>session,metastore,query,quota,scheduler,index,log,savedquery</value>
     <description>These JAX-RS resources would be started in the specified order when lens-server starts up</description>
   </property>
 
@@ -371,6 +377,12 @@
   </property>
 
   <property>
+    <name>lens.server.savedquery.ws.resource.impl</name>
+    <value>org.apache.lens.server.query.save.SavedQueryResource</value>
+    <description>Implementation class for Saved query Resource</description>
+  </property>
+
+  <property>
     <name>lens.server.query.ws.resource.impl</name>
     <value>org.apache.lens.server.query.QueryServiceResource</value>
     <description>Implementation class for Query Resource</description>
@@ -753,4 +765,21 @@
       implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.</description>
   </property>
 
+  <property>
+    <name>lens.server.savedquery.jdbc.dialectclass</name>
+    <value>org.apache.lens.server.query.save.SavedQueryDao$HSQLDialect</value>
+    <description>Dialect of the target DB, Default is HSQL. Override with the target DB used.</description>
+  </property>
+
+  <property>
+    <name>lens.server.savedquery.list.default.offset</name>
+    <value>0</value>
+    <description>Key denoting the default start value of saved query list api.</description>
+  </property>
+  <property>
+    <name>lens.server.savedquery.list.default.count</name>
+    <value>20</value>
+    <description>Key denoting the default fetch value of saved query list api.</description>
+  </property>
+
 </configuration>

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/test/java/org/apache/lens/server/query/save/TestSavedQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/save/TestSavedQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/save/TestSavedQueryService.java
new file mode 100644
index 0000000..7c6ce49
--- /dev/null
+++ b/lens-server/src/test/java/org/apache/lens/server/query/save/TestSavedQueryService.java
@@ -0,0 +1,274 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.save;
+
+import static org.apache.lens.api.query.save.ParameterCollectionType.SINGLE;
+import static org.apache.lens.api.query.save.ParameterDataType.STRING;
+
+import static org.testng.Assert.*;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.*;
+
+import org.apache.lens.api.LensSessionHandle;
+import org.apache.lens.api.jaxb.LensJAXBContextResolver;
+import org.apache.lens.api.query.save.*;
+import org.apache.lens.server.LensJerseyTest;
+import org.apache.lens.server.LensServices;
+import org.apache.lens.server.api.metrics.MetricsService;
+import org.apache.lens.server.api.query.QueryExecutionService;
+import org.apache.lens.server.api.query.save.SavedQueryService;
+import org.apache.lens.server.error.LensExceptionMapper;
+import org.apache.lens.server.query.QueryExecutionServiceImpl;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import com.beust.jcommander.internal.Maps;
+import com.beust.jcommander.internal.Sets;
+import com.google.common.collect.Lists;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Test(groups = "unit-test")
+public class TestSavedQueryService extends LensJerseyTest {
+  SavedQueryServiceImpl savedQueryService;
+  QueryExecutionServiceImpl queryService;
+  MetricsService metricsSvc;
+  LensSessionHandle lensSessionId;
+
+  private static final String QUERY_STRING = "select * from table where "
+    + "col = :param1 ";
+
+  private static final SavedQuery QUERY = new SavedQuery(
+    1,
+    "query_name",
+    "description",
+    QUERY_STRING
+    ,
+    Lists.newArrayList(
+      new Parameter(
+        "param1", "Param1", new String[]{"val"}, STRING, SINGLE
+      )
+    )
+  );
+
+  public static class SavedQueryTestApp extends SavedQueryApp {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+      final Set<Class<?>> classes = super.getClasses();
+      classes.add(LensExceptionMapper.class);
+      classes.add(LensJAXBContextResolver.class);
+      return classes;
+    }
+  }
+
+  @BeforeTest
+  public void setUp() throws Exception {
+    super.setUp();
+    savedQueryService = LensServices.get().getService(SavedQueryService.NAME);
+    queryService = LensServices.get().getService(QueryExecutionService.NAME);
+    metricsSvc = LensServices.get().getService(MetricsService.NAME);
+    Map<String, String> sessionconf = Maps.newHashMap();
+    sessionconf.put("test.session.key", "svalue");
+    lensSessionId = queryService.openSession("foo", "bar", sessionconf); // @localhost should be removed
+  }
+
+  @AfterTest
+  public void tearDown() throws Exception {
+    super.tearDown();
+    queryService.closeSession(lensSessionId);
+    super.tearDown();
+  }
+
+  @Override
+  protected Application configure() {
+    return new SavedQueryTestApp();
+  }
+
+  @Override
+  protected void configureClient(ClientConfig config) {
+    config.register(MultiPartFeature.class);
+    config.register(LensJAXBContextResolver.class);
+  }
+
+  @Test
+  public void testResource() throws InterruptedException {
+    assertEquals(
+      savedQueriesRoot().path("health").request().get().getStatus(),
+      200,
+      "Saved query resource is not up"
+    );
+  }
+
+  private WebTarget savedQueriesRoot() {
+    return target()
+      .path("queryapi")
+      .path("savedqueries");
+  }
+
+  private ResourceModifiedResponse updateQuery(long id) {
+    Response savedquery = savedQueriesRoot()
+      .path(String.valueOf(id))
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .put(Entity.json(QUERY));
+    savedquery.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return savedquery.readEntity(ResourceModifiedResponse.class);
+  }
+
+  private ResourceModifiedResponse deleteQuery(long id) {
+    Response savedquery = savedQueriesRoot()
+      .path(String.valueOf(id))
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .delete();
+    savedquery.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return savedquery.readEntity(ResourceModifiedResponse.class);
+  }
+
+  private SavedQuery get(long id) {
+    Response savedquery = savedQueriesRoot()
+      .path(String.valueOf(id))
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .get();
+    savedquery.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return savedquery.readEntity(SavedQuery.class);
+  }
+
+  private ParameterParserResponse extractParameters() {
+    Response parameters = savedQueriesRoot()
+      .path("parameters")
+      .queryParam("query", QUERY_STRING)
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .get();
+    parameters.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return parameters.readEntity(ParameterParserResponse.class);
+  }
+
+  private ResourceModifiedResponse saveQuery() {
+    Response savedquery = savedQueriesRoot()
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .post(Entity.json(QUERY));
+    savedquery.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return savedquery.readEntity(ResourceModifiedResponse.class);
+  }
+
+  private ListResponse list(long offset, long count) {
+    Response savedquery = savedQueriesRoot()
+      .queryParam("start", offset)
+      .queryParam("count", count)
+      .request(MediaType.APPLICATION_JSON_TYPE)
+      .accept(MediaType.APPLICATION_JSON_TYPE)
+      .get();
+    savedquery.getStringHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
+    return savedquery.readEntity(ListResponse.class);
+  }
+
+  @Test
+  public void testSaveQuery() {
+    assertEquals(saveQuery().getStatus(), ResourceModifiedResponse.Action.CREATED);
+  }
+
+  @Test
+  public void testUpdateQuery() {
+    ResourceModifiedResponse saved = saveQuery();
+    ResourceModifiedResponse updated = updateQuery(saved.getId());
+    assertEquals(updated.getStatus(), ResourceModifiedResponse.Action.UPDATED);
+    assertEquals(updated.getId(), saved.getId());
+  }
+
+  @Test
+  public void testUpdateQueryNonExistentResource() {
+    try {
+      updateQuery(99999);
+      fail("Did not fail when querying for a non existent resource");
+    } catch (Throwable e) {
+      assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testGetQuery() {
+    final long id = saveQuery().getId();
+    SavedQuery savedQuery = get(id);
+    assertEquals(savedQuery.getId(), id);
+  }
+
+  @Test
+  public void testGetQueryNonExistentResource() {
+    try {
+      get(99999);
+      fail("Did not fail when querying for a non existent resource");
+    } catch (Throwable e) {
+      assertTrue(true);
+    }
+  }
+
+  @Test
+  public void testListQuery() {
+    final Set<Long> ids = Sets.newHashSet();
+    ids.add(saveQuery().getId());
+    ids.add(saveQuery().getId());
+    ids.add(saveQuery().getId());
+    ids.add(saveQuery().getId());
+    final ListResponse list = list(0, 4);
+    final List<SavedQuery> queries = list.getResoures();
+    assertEquals(ids.size(), queries.size());
+  }
+
+  @Test
+  public void testDeleteQuery() {
+    long id = saveQuery().getId();
+    deleteQuery(id);
+    try {
+      get(id);
+      fail("Resource not deleted");
+    } catch (Throwable e) {
+      assertTrue(true);
+    }
+
+  }
+
+  @Test
+  public void testDeleteQueryNonExistentResource() {
+    long id = saveQuery().getId();
+    deleteQuery(id);
+    try {
+      deleteQuery(id);
+      fail("Succeeded in deleting a non existent resource");
+    } catch (Throwable e) {
+      assertTrue(true);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/lens-server/src/test/resources/lens-site.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/test/resources/lens-site.xml b/lens-server/src/test/resources/lens-site.xml
index 4cf94d5..f728810 100644
--- a/lens-server/src/test/resources/lens-site.xml
+++ b/lens-server/src/test/resources/lens-site.xml
@@ -97,7 +97,7 @@
 
   <property>
     <name>lens.server.ws.resourcenames</name>
-    <value>session,metastore,query,quota,scheduler,index,log,test</value>
+    <value>session,metastore,query,quota,scheduler,index,log,test,savedquery</value>
     <description>These JAX-RS resources would be started in the specified order when lens-server starts up</description>
   </property>
 
@@ -108,6 +108,12 @@
   </property>
 
   <property>
+    <name>lens.server.savedquery.ws.resource.impl</name>
+    <value>org.apache.lens.server.query.save.SavedQueryResource</value>
+    <description>Implementation class for saved query Resource</description>
+  </property>
+
+  <property>
     <name>lens.server.user.resolver.type</name>
     <value>FIXED</value>
   </property>
@@ -132,8 +138,14 @@
   </property>
 
   <property>
+    <name>lens.server.savedquery.jdbc.dialectclass</name>
+    <value>org.apache.lens.server.query.save.SavedQueryDao$HSQLDialect</value>
+    <description>Dialect of the target DB, Default is HSQL</description>
+  </property>
+
+  <property>
     <name>lens.server.servicenames</name>
-    <value>session,query,metastore,scheduler,quota,mocknonlens</value>
+    <value>session,query,metastore,scheduler,quota,mocknonlens,savedquery</value>
   </property>
 
   <property>
@@ -143,6 +155,12 @@
   </property>
 
   <property>
+    <name>lens.server.savedquery.service.impl</name>
+    <value>org.apache.lens.server.query.save.SavedQueryServiceImpl</value>
+    <description>Implementation class for saved query service</description>
+  </property>
+
+  <property>
     <name>lens.server.ws.filternames</name>
     <value>authentication,consistentState,serverMode,logging</value>
     <description>These JAX-RS filters would be started in the specified order when lens-server starts up</description>

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/src/site/apt/admin/config.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/admin/config.apt b/src/site/apt/admin/config.apt
index b163a3a..3500441 100644
--- a/src/site/apt/admin/config.apt
+++ b/src/site/apt/admin/config.apt
@@ -147,86 +147,96 @@ Lens server configuration
 *--+--+---+--+
 |59|lens.server.restart.enabled|true|If flag is enabled, all the services will be persisted to persistent location passed.|
 *--+--+---+--+
-|60|lens.server.scheduler.service.impl|org.apache.lens.server.scheduler.QuerySchedulerServiceImpl|Implementation class for query scheduler service|
+|60|lens.server.savedquery.jdbc.dialectclass|org.apache.lens.server.query.save.SavedQueryDao$HSQLDialect|Dialect of the target DB, Default is HSQL. Override with the target DB used.|
 *--+--+---+--+
-|61|lens.server.scheduler.ws.resource.impl|org.apache.lens.server.scheduler.ScheduleResource|Implementation class for query scheduler resource|
+|61|lens.server.savedquery.list.default.count|20|Key denoting the default fetch value of saved query list api.|
 *--+--+---+--+
-|62|lens.server.scheduling.queue.poll.interval.millisec|2000|The interval at which submission thread will poll scheduling queue to fetch the next query for submission. If value is less than equal to 0, then it would mean that thread will continuosly poll without sleeping. The interval has to be given in milliseconds.|
+|62|lens.server.savedquery.list.default.offset|0|Key denoting the default start value of saved query list api.|
 *--+--+---+--+
-|63|lens.server.serverMode.ws.filter.impl|org.apache.lens.server.ServerModeFilter|Implementation class for ServerMode Filter|
+|63|lens.server.savedquery.service.impl|org.apache.lens.server.query.save.SavedQueryServiceImpl|Implementation class for saved query service|
 *--+--+---+--+
-|64|lens.server.service.provider.factory|org.apache.lens.server.ServiceProviderFactoryImpl|Service provider factory implementation class. This parameter is used to lookup the factory implementation class name that would provide an instance of ServiceProvider. Users should instantiate the class to obtain its instance. Example -- Class spfClass = conf.getClass("lens.server.service.provider.factory", null, ServiceProviderFactory.class); ServiceProviderFactory spf = spfClass.newInstance(); ServiceProvider serviceProvider = spf.getServiceProvider(); -- This is not supposed to be overridden by users.|
+|64|lens.server.savedquery.ws.resource.impl|org.apache.lens.server.query.save.SavedQueryResource|Implementation class for Saved query Resource|
 *--+--+---+--+
-|65|lens.server.servicenames|session,query,metastore,scheduler,quota|These services would be started in the specified order when lens-server starts up|
+|65|lens.server.scheduler.service.impl|org.apache.lens.server.scheduler.QuerySchedulerServiceImpl|Implementation class for query scheduler service|
 *--+--+---+--+
-|66|lens.server.session.expiry.service.interval.secs|3600|Interval at which lens session expiry service runs|
+|66|lens.server.scheduler.ws.resource.impl|org.apache.lens.server.scheduler.ScheduleResource|Implementation class for query scheduler resource|
 *--+--+---+--+
-|67|lens.server.session.service.impl|org.apache.lens.server.session.HiveSessionService|Implementation class for session service|
+|67|lens.server.scheduling.queue.poll.interval.millisec|2000|The interval at which submission thread will poll scheduling queue to fetch the next query for submission. If value is less than equal to 0, then it would mean that thread will continuosly poll without sleeping. The interval has to be given in milliseconds.|
 *--+--+---+--+
-|68|lens.server.session.timeout.seconds|86400|Lens session timeout in seconds.If there is no activity on the session for this period then the session will be closed.Default timeout is one day.|
+|68|lens.server.serverMode.ws.filter.impl|org.apache.lens.server.ServerModeFilter|Implementation class for ServerMode Filter|
 *--+--+---+--+
-|69|lens.server.session.ws.resource.impl|org.apache.lens.server.session.SessionResource|Implementation class for Session Resource|
+|69|lens.server.service.provider.factory|org.apache.lens.server.ServiceProviderFactoryImpl|Service provider factory implementation class. This parameter is used to lookup the factory implementation class name that would provide an instance of ServiceProvider. Users should instantiate the class to obtain its instance. Example -- Class spfClass = conf.getClass("lens.server.service.provider.factory", null, ServiceProviderFactory.class); ServiceProviderFactory spf = spfClass.newInstance(); ServiceProvider serviceProvider = spf.getServiceProvider(); -- This is not supposed to be overridden by users.|
 *--+--+---+--+
-|70|lens.server.snapshot.interval|300000|Snapshot interval time in miliseconds for saving lens server state.|
+|70|lens.server.servicenames|session,query,metastore,scheduler,quota,savedquery|These services would be started in the specified order when lens-server starts up|
 *--+--+---+--+
-|71|lens.server.state.persist.out.stream.buffer.size|1048576|Output Stream Buffer Size used in writing lens server state to file system. Size is in bytes.|
+|71|lens.server.session.expiry.service.interval.secs|3600|Interval at which lens session expiry service runs|
 *--+--+---+--+
-|72|lens.server.statistics.db|lensstats|Database to which statistics tables are created and partitions are added.|
+|72|lens.server.session.service.impl|org.apache.lens.server.session.HiveSessionService|Implementation class for session service|
 *--+--+---+--+
-|73|lens.server.statistics.log.rollover.interval|3600000|Default rate which log statistics store scans for rollups in milliseconds.|
+|73|lens.server.session.timeout.seconds|86400|Lens session timeout in seconds.If there is no activity on the session for this period then the session will be closed.Default timeout is one day.|
 *--+--+---+--+
-|74|lens.server.statistics.store.class|org.apache.lens.server.stats.store.log.LogStatisticsStore|Default implementation of class used to persist Lens Statistics.|
+|74|lens.server.session.ws.resource.impl|org.apache.lens.server.session.SessionResource|Implementation class for Session Resource|
 *--+--+---+--+
-|75|lens.server.statistics.warehouse.dir|file:///tmp/lens/statistics/warehouse|Default top level location where stats are moved by the log statistics store.|
+|75|lens.server.snapshot.interval|300000|Snapshot interval time in miliseconds for saving lens server state.|
 *--+--+---+--+
-|76|lens.server.total.query.cost.ceiling.per.user|-1.0|A query submitted by user will be launched only if total query cost of all current launched queries of user is less than or equal to total query cost ceiling defined by this property. This configuration value is only useful when TotalQueryCostCeilingConstraint is enabled by using org.apache.lens.server.query.constraint.TotalQueryCostCeilingConstraintFactory as one of the factories in lens.server.query.constraint.factories property. Default is -1.0 which means that there is no limit on the total query cost of launched queries submitted by a user.|
+|76|lens.server.state.persist.out.stream.buffer.size|1048576|Output Stream Buffer Size used in writing lens server state to file system. Size is in bytes.|
 *--+--+---+--+
-|77|lens.server.ui.base.uri|http://0.0.0.0:19999/|The base url for the Lens UI Server|
+|77|lens.server.statistics.db|lensstats|Database to which statistics tables are created and partitions are added.|
 *--+--+---+--+
-|78|lens.server.ui.enable|true|Bringing up the ui server is optional. By default it brings up UI server.|
+|78|lens.server.statistics.log.rollover.interval|3600000|Default rate which log statistics store scans for rollups in milliseconds.|
 *--+--+---+--+
-|79|lens.server.ui.enable.caching|true|Set this to false to disable static file caching in the UI server|
+|79|lens.server.statistics.store.class|org.apache.lens.server.stats.store.log.LogStatisticsStore|Default implementation of class used to persist Lens Statistics.|
 *--+--+---+--+
-|80|lens.server.ui.static.dir|webapp/lens-server/static|The base directory to server UI static files from|
+|80|lens.server.statistics.warehouse.dir|file:///tmp/lens/statistics/warehouse|Default top level location where stats are moved by the log statistics store.|
 *--+--+---+--+
-|81|lens.server.user.resolver.custom.class|full.package.name.Classname|Required for CUSTOM user resolver. In case the provided implementations are not sufficient for user config resolver, a custom classname can be provided. Class should extend org.apache.lens.server.user.UserConfigLoader|
+|81|lens.server.total.query.cost.ceiling.per.user|-1.0|A query submitted by user will be launched only if total query cost of all current launched queries of user is less than or equal to total query cost ceiling defined by this property. This configuration value is only useful when TotalQueryCostCeilingConstraint is enabled by using org.apache.lens.server.query.constraint.TotalQueryCostCeilingConstraintFactory as one of the factories in lens.server.query.constraint.factories property. Default is -1.0 which means that there is no limit on the total query cost of launched queries submitted by a user.|
 *--+--+---+--+
-|82|lens.server.user.resolver.db.keys|lens.session.cluster.user,mapred.job.queue.name|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loaders, the conf keys that will be loaded from database.|
+|82|lens.server.ui.base.uri|http://0.0.0.0:19999/|The base url for the Lens UI Server|
 *--+--+---+--+
-|83|lens.server.user.resolver.db.query|select clusteruser,queue from user_config_table where username=?|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loader, this query will be run with single argument = logged in user and the result columns will be assigned to lens.server.user.resolver.db.keys in order. For ldap backed database resolver, the argument to this query will be the intermediate values obtained from ldap.|
+|83|lens.server.ui.enable|true|Bringing up the ui server is optional. By default it brings up UI server.|
 *--+--+---+--+
-|84|lens.server.user.resolver.fixed.value| |Required for FIXED user resolver. when lens.server.user.resolver.type=FIXED, This will be the value cluster user will resolve to.|
+|84|lens.server.ui.enable.caching|true|Set this to false to disable static file caching in the UI server|
 *--+--+---+--+
-|85|lens.server.user.resolver.ldap.bind.dn| |Required for LDAP_BACKED_DATABASE user resolvers. ldap dn for admin binding example: CN=company-it-admin,ou=service-account,ou=company-service-account,dc=dc1,dc=com...|
+|85|lens.server.ui.static.dir|webapp/lens-server/static|The base directory to server UI static files from|
 *--+--+---+--+
-|86|lens.server.user.resolver.ldap.bind.password| |Required for LDAP_BACKED_DATABASE user resolvers. ldap password for admin binding above|
+|86|lens.server.user.resolver.custom.class|full.package.name.Classname|Required for CUSTOM user resolver. In case the provided implementations are not sufficient for user config resolver, a custom classname can be provided. Class should extend org.apache.lens.server.user.UserConfigLoader|
 *--+--+---+--+
-|87|lens.server.user.resolver.ldap.fields|department|Required for LDAP_BACKED_DATABASE user resolvers. list of fields to be obtained from ldap. These will be cached by the intermediate db.|
+|87|lens.server.user.resolver.db.keys|lens.session.cluster.user,mapred.job.queue.name|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loaders, the conf keys that will be loaded from database.|
 *--+--+---+--+
-|88|lens.server.user.resolver.ldap.intermediate.db.delete.sql|delete from user_department where username=?|Required for LDAP_BACKED_DATABASE user resolvers. query to delete intermediate values from database backing ldap as cache. one argument: logged in user.|
+|88|lens.server.user.resolver.db.query|select clusteruser,queue from user_config_table where username=?|Required for DATABASE and LDAP_BACKED_DATABASE user resolvers. For database based user config loader, this query will be run with single argument = logged in user and the result columns will be assigned to lens.server.user.resolver.db.keys in order. For ldap backed database resolver, the argument to this query will be the intermediate values obtained from ldap.|
 *--+--+---+--+
-|89|lens.server.user.resolver.ldap.intermediate.db.insert.sql|insert into user_department (username, department, expiry) values (?, ?, ?)|Required for LDAP_BACKED_DATABASE user resolvers. query to insert intermediate values from database backing ldap as cache. arguments: first logged in user, then all intermediate values, then current time + expiration time|
+|89|lens.server.user.resolver.fixed.value| |Required for FIXED user resolver. when lens.server.user.resolver.type=FIXED, This will be the value cluster user will resolve to.|
 *--+--+---+--+
-|90|lens.server.user.resolver.ldap.intermediate.db.query|select department from user_department where username=? and expiry>?|Required for LDAP_BACKED_DATABASE user resolvers. query to obtain intermediate values from database backing ldap as cache. two arguments: logged in user and current time.|
+|90|lens.server.user.resolver.ldap.bind.dn| |Required for LDAP_BACKED_DATABASE user resolvers. ldap dn for admin binding example: CN=company-it-admin,ou=service-account,ou=company-service-account,dc=dc1,dc=com...|
 *--+--+---+--+
-|91|lens.server.user.resolver.ldap.search.base| |Required for LDAP_BACKED_DATABASE user resolvers. for searching intermediate values for a user, the search keys. example: cn=users,dc=dc1,dc=dc2...|
+|91|lens.server.user.resolver.ldap.bind.password| |Required for LDAP_BACKED_DATABASE user resolvers. ldap password for admin binding above|
 *--+--+---+--+
-|92|lens.server.user.resolver.ldap.search.filter|(&(objectClass=user)(sAMAccountName=%s))|Required for LDAP_BACKED_DATABASE user resolvers. filter pattern for ldap search|
+|92|lens.server.user.resolver.ldap.fields|department|Required for LDAP_BACKED_DATABASE user resolvers. list of fields to be obtained from ldap. These will be cached by the intermediate db.|
 *--+--+---+--+
-|93|lens.server.user.resolver.ldap.url| |Required for LDAP_BACKED_DATABASE user resolvers. ldap url to connect to.|
+|93|lens.server.user.resolver.ldap.intermediate.db.delete.sql|delete from user_department where username=?|Required for LDAP_BACKED_DATABASE user resolvers. query to delete intermediate values from database backing ldap as cache. one argument: logged in user.|
 *--+--+---+--+
-|94|lens.server.user.resolver.propertybased.filename|/path/to/propertyfile|Required for PROPERTYBASED user resolver. when lens.server.user.resolver.type is PROPERTYBASED, then this file will be read and parsed to determine cluster user. Each line should contain username followed by DOT followed by property full name followed by equal-to sign and followed by value. example schema of the file is: user1.lens.server.cluster.user=clusteruser1 user1.mapred.job.queue.name=queue1 *.lens.server.cluster.user=defaultclusteruser *.mapred.job.queue.name=default|
+|94|lens.server.user.resolver.ldap.intermediate.db.insert.sql|insert into user_department (username, department, expiry) values (?, ?, ?)|Required for LDAP_BACKED_DATABASE user resolvers. query to insert intermediate values from database backing ldap as cache. arguments: first logged in user, then all intermediate values, then current time + expiration time|
 *--+--+---+--+
-|95|lens.server.user.resolver.type|FIXED|Type of user config resolver. allowed values are FIXED, PROPERTYBASED, DATABASE, LDAP_BACKED_DATABASE, CUSTOM.|
+|95|lens.server.user.resolver.ldap.intermediate.db.query|select department from user_department where username=? and expiry>?|Required for LDAP_BACKED_DATABASE user resolvers. query to obtain intermediate values from database backing ldap as cache. two arguments: logged in user and current time.|
 *--+--+---+--+
-|96|lens.server.waiting.queries.selection.policy.factories|org.apache.lens.server.query.collect.UserSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+|96|lens.server.user.resolver.ldap.search.base| |Required for LDAP_BACKED_DATABASE user resolvers. for searching intermediate values for a user, the search keys. example: cn=users,dc=dc1,dc=dc2...|
 *--+--+---+--+
-|97|lens.server.ws.featurenames|multipart|These JAX-RS Feature(s) would be started in the specified order when lens-server starts up|
+|97|lens.server.user.resolver.ldap.search.filter|(&(objectClass=user)(sAMAccountName=%s))|Required for LDAP_BACKED_DATABASE user resolvers. filter pattern for ldap search|
 *--+--+---+--+
-|98|lens.server.ws.filternames|authentication,consistentState,serverMode|These JAX-RS filters would be started in the specified order when lens-server starts up|
+|98|lens.server.user.resolver.ldap.url| |Required for LDAP_BACKED_DATABASE user resolvers. ldap url to connect to.|
 *--+--+---+--+
-|99|lens.server.ws.listenernames|appevent|These listeners would be called in the specified order when lens-server starts up|
+|99|lens.server.user.resolver.propertybased.filename|/path/to/propertyfile|Required for PROPERTYBASED user resolver. when lens.server.user.resolver.type is PROPERTYBASED, then this file will be read and parsed to determine cluster user. Each line should contain username followed by DOT followed by property full name followed by equal-to sign and followed by value. example schema of the file is: user1.lens.server.cluster.user=clusteruser1 user1.mapred.job.queue.name=queue1 *.lens.server.cluster.user=defaultclusteruser *.mapred.job.queue.name=default|
 *--+--+---+--+
-|100|lens.server.ws.resourcenames|session,metastore,query,quota,scheduler,index,log|These JAX-RS resources would be started in the specified order when lens-server starts up|
+|100|lens.server.user.resolver.type|FIXED|Type of user config resolver. allowed values are FIXED, PROPERTYBASED, DATABASE, LDAP_BACKED_DATABASE, CUSTOM.|
+*--+--+---+--+
+|101|lens.server.waiting.queries.selection.policy.factories|org.apache.lens.server.query.collect.UserSpecificWaitingQueriesSelectionPolicyFactory|Factories used to instantiate waiting queries selection policies. Every factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+*--+--+---+--+
+|102|lens.server.ws.featurenames|multipart|These JAX-RS Feature(s) would be started in the specified order when lens-server starts up|
+*--+--+---+--+
+|103|lens.server.ws.filternames|authentication,consistentState,serverMode|These JAX-RS filters would be started in the specified order when lens-server starts up|
+*--+--+---+--+
+|104|lens.server.ws.listenernames|appevent|These listeners would be called in the specified order when lens-server starts up|
+*--+--+---+--+
+|105|lens.server.ws.resourcenames|session,metastore,query,quota,scheduler,index,log,savedquery|These JAX-RS resources would be started in the specified order when lens-server starts up|
 *--+--+---+--+
 The configuration parameters and their default values

http://git-wip-us.apache.org/repos/asf/lens/blob/4e81ef4d/src/site/apt/user/index.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/user/index.apt b/src/site/apt/user/index.apt
index 6a86b1b..812239e 100644
--- a/src/site/apt/user/index.apt
+++ b/src/site/apt/user/index.apt
@@ -191,6 +191,29 @@ Lens User Guide
 
   * {{{./cli.html#Query_Management} CLI query management}}
 
+** Saved queries
+
+  A query can be saved for future execution.
+
+  * Parts of a query could also be parameterised. Values for the parameters can be provided at the time of executing the saved query. If value is not provided, the default value provided at the time of saving the query will be used.
+
+  * Any part of the query could be parameterised. The parameters are mapped with a data type and collection type.
+
+  * During the execution,
+   - STRING parameter will be replaced with a single quoted value
+   - NUMBER, DECIMAL and BOOLEAN will be parsed and resolved (exception will be thrown if the given value is not parsable as the data types mentioned)
+
+  * And collection types,
+	 - SINGLE will be replaced by the simple encoded value
+	 - MULTIPLE will be replaced by (<v1>, <v2>... <vn>)
+	Eg. {select col from table where col = :param}  (param is the parameter)
+	 - If :param is SINGLE and STRING, the query would be resolved to {select col from table where col = '<val>'}
+	 - If :param is SINGLE and NUMBER per se, the query would be resolved to {select col from table where col = 5}
+
+	* A query handle is returned when a saved query is ran.
+
+  * {{{../resource_SavedQueryResource.html}Rest api for saved queries}}
+
 * Metastore service
 
 	The Metastore service is used for DDL operations like creating, updating cubes, fact tables and dimensions. It also pprovides endpoints to create storage tables and to add partitions to a storage table. For more detailed information see the {{{../resource_MetastoreResource.html}metastore service resource}} documentation.


[36/50] [abbrv] lens git commit: LENS-576 : Cannot retrieve query results on lens server restart

Posted by ra...@apache.org.
LENS-576 : Cannot retrieve query results on lens server restart


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/5bae273e
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/5bae273e
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/5bae273e

Branch: refs/heads/current-release-line
Commit: 5bae273eef68396e42a3678b1182b529c6e42d69
Parents: b2c8fc0
Author: Deepak Barr <de...@gmail.com>
Authored: Fri Sep 25 13:39:44 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Fri Sep 25 13:39:44 2015 +0530

----------------------------------------------------------------------
 .../lens/lib/query/AbstractFileFormatter.java   | 18 +++++
 .../lens/lib/query/WrappedFileFormatter.java    | 13 ++++
 .../lib/query/MockLensResultSetMetadata.java    | 65 +++++++++++++++++
 .../lib/query/TestAbstractFileFormatter.java    | 73 +++++++++++---------
 .../api/driver/LensResultSetMetadata.java       | 49 +++++++++++++
 .../lens/server/api/query/QueryContext.java     |  2 +-
 .../server/api/query/QueryOutputFormatter.java  |  3 +-
 .../lens/server/query/LensPersistentResult.java |  6 +-
 .../server/query/QueryExecutionServiceImpl.java | 39 +----------
 9 files changed, 193 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-query-lib/src/main/java/org/apache/lens/lib/query/AbstractFileFormatter.java
----------------------------------------------------------------------
diff --git a/lens-query-lib/src/main/java/org/apache/lens/lib/query/AbstractFileFormatter.java b/lens-query-lib/src/main/java/org/apache/lens/lib/query/AbstractFileFormatter.java
index ae5af03..8c06621 100644
--- a/lens-query-lib/src/main/java/org/apache/lens/lib/query/AbstractFileFormatter.java
+++ b/lens-query-lib/src/main/java/org/apache/lens/lib/query/AbstractFileFormatter.java
@@ -19,6 +19,8 @@
 package org.apache.lens.lib.query;
 
 import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 
 import org.apache.lens.server.api.driver.LensResultSetMetadata;
 import org.apache.lens.server.api.query.QueryContext;
@@ -90,4 +92,20 @@ public abstract class AbstractFileFormatter extends AbstractOutputFormatter impl
   public String getFinalOutputPath() {
     return finalPath.toString();
   }
+
+  @Override
+  public void writeExternal(ObjectOutput out) throws IOException {
+    out.writeUTF(metadata.toJson());
+    out.writeUTF(finalPath.toString());
+    out.writeInt(numRows);
+    out.writeLong(fileSize);
+  }
+
+  @Override
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    metadata = LensResultSetMetadata.fromJson(in.readUTF());
+    finalPath = new Path(in.readUTF());
+    numRows = in.readInt();
+    fileSize = in.readLong();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-query-lib/src/main/java/org/apache/lens/lib/query/WrappedFileFormatter.java
----------------------------------------------------------------------
diff --git a/lens-query-lib/src/main/java/org/apache/lens/lib/query/WrappedFileFormatter.java b/lens-query-lib/src/main/java/org/apache/lens/lib/query/WrappedFileFormatter.java
index e28c17b..5910709 100644
--- a/lens-query-lib/src/main/java/org/apache/lens/lib/query/WrappedFileFormatter.java
+++ b/lens-query-lib/src/main/java/org/apache/lens/lib/query/WrappedFileFormatter.java
@@ -19,6 +19,8 @@
 package org.apache.lens.lib.query;
 
 import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 
 import org.apache.lens.server.api.driver.LensResultSetMetadata;
 import org.apache.lens.server.api.query.QueryContext;
@@ -137,4 +139,15 @@ public abstract class WrappedFileFormatter extends AbstractOutputFormatter {
   public String getEncoding() {
     return formatter.getEncoding();
   }
+
+  @Override
+  public void writeExternal(ObjectOutput out) throws IOException {
+    out.writeObject(formatter);
+  }
+
+  @Override
+  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    formatter = (AbstractFileFormatter) in.readObject();
+    metadata = formatter.getMetadata();
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-query-lib/src/test/java/org/apache/lens/lib/query/MockLensResultSetMetadata.java
----------------------------------------------------------------------
diff --git a/lens-query-lib/src/test/java/org/apache/lens/lib/query/MockLensResultSetMetadata.java b/lens-query-lib/src/test/java/org/apache/lens/lib/query/MockLensResultSetMetadata.java
new file mode 100644
index 0000000..3b6c0e4
--- /dev/null
+++ b/lens-query-lib/src/test/java/org/apache/lens/lib/query/MockLensResultSetMetadata.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.lib.query;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.lens.server.api.driver.LensResultSetMetadata;
+
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hive.service.cli.ColumnDescriptor;
+
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+public class MockLensResultSetMetadata extends LensResultSetMetadata {
+  List<ColumnDescriptor> columns;
+
+  @Override
+  public List<ColumnDescriptor> getColumns() {
+    return columns;
+  }
+
+  public static LensResultSetMetadata createMockedResultSet() {
+    List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
+    columns.add(new ColumnDescriptor(new FieldSchema("firstcol", "int", ""), 0));
+    columns.add(new ColumnDescriptor(new FieldSchema("format(secondcol,2)", "string", ""), 1));
+    columns.add(new ColumnDescriptor(new FieldSchema("thirdcol", "varchar(20)", ""), 2));
+    columns.add(new ColumnDescriptor(new FieldSchema("fourthcol", "char(15)", ""), 3));
+    columns.add(new ColumnDescriptor(new FieldSchema("fifthcol", "array<tinyint>", ""), 4));
+    columns.add(new ColumnDescriptor(new FieldSchema("sixthcol", "struct<a:int,b:varchar(10)>", ""), 5));
+    columns.add(new ColumnDescriptor(new FieldSchema("seventhcol", "map<int,char(10)>", ""), 6));
+    return new MockLensResultSetMetadata(columns);
+  }
+
+  public static LensResultSetMetadata createMockedResultSetWithoutComma() {
+    List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
+    columns.add(new ColumnDescriptor(new FieldSchema("firstcol", "int", ""), 0));
+    columns.add(new ColumnDescriptor(new FieldSchema("secondcol", "string", ""), 1));
+    columns.add(new ColumnDescriptor(new FieldSchema("thirdcol", "varchar(20)", ""), 2));
+    columns.add(new ColumnDescriptor(new FieldSchema("fourthcol", "char(15)", ""), 3));
+    columns.add(new ColumnDescriptor(new FieldSchema("fifthcol", "array<tinyint>", ""), 4));
+    columns.add(new ColumnDescriptor(new FieldSchema("sixthcol", "struct<a:int,b:varchar(10)>", ""), 5));
+    columns.add(new ColumnDescriptor(new FieldSchema("seventhcol", "map<int,char(10)>", ""), 6));
+    return new MockLensResultSetMetadata(columns);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-query-lib/src/test/java/org/apache/lens/lib/query/TestAbstractFileFormatter.java
----------------------------------------------------------------------
diff --git a/lens-query-lib/src/test/java/org/apache/lens/lib/query/TestAbstractFileFormatter.java b/lens-query-lib/src/test/java/org/apache/lens/lib/query/TestAbstractFileFormatter.java
index 35d7a00..40e1cdc 100644
--- a/lens-query-lib/src/test/java/org/apache/lens/lib/query/TestAbstractFileFormatter.java
+++ b/lens-query-lib/src/test/java/org/apache/lens/lib/query/TestAbstractFileFormatter.java
@@ -19,8 +19,13 @@
 package org.apache.lens.lib.query;
 
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.zip.ZipEntry;
@@ -37,10 +42,8 @@ import org.apache.lens.server.api.query.QueryContext;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.hadoop.io.compress.CompressionCodec;
 import org.apache.hadoop.io.compress.CompressionCodecFactory;
-import org.apache.hive.service.cli.ColumnDescriptor;
 
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -189,6 +192,39 @@ public abstract class TestAbstractFileFormatter {
   }
 
   /**
+   * Test formatter persistence
+   *
+   * @throws IOException Signals that an I/O exception has occurred.
+   */
+  @Test
+  public void testFormatterPersistence() throws IOException, ClassNotFoundException {
+    Configuration conf = new Configuration();
+    setConf(conf);
+    testFormatter(conf, "UTF8", LensConfConstants.RESULT_SET_PARENT_DIR_DEFAULT, ".csv", getMockedResultSet());
+
+    // Write formatter to stream
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try {
+      new ObjectOutputStream(outputStream).writeObject(formatter);
+    } finally {
+      outputStream.close();
+    }
+    // Create another formatter from the stream
+    ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+    WrappedFileFormatter newFormatter = createFormatter();
+    try {
+      newFormatter=(WrappedFileFormatter)new ObjectInputStream(inputStream).readObject();
+    } finally {
+      inputStream.close();
+    }
+
+    Assert.assertEquals(formatter.getFinalOutputPath(), newFormatter.getFinalOutputPath());
+    Assert.assertEquals(formatter.getFileSize(), newFormatter.getFileSize());
+    Assert.assertEquals(formatter.getNumRows(), newFormatter.getNumRows());
+    Assert.assertEquals(formatter.getMetadata().toJson(), newFormatter.getMetadata().toJson());
+  }
+
+  /**
    * Creates the formatter.
    *
    * @return the wrapped file formatter
@@ -265,6 +301,7 @@ public abstract class TestAbstractFileFormatter {
     Assert.assertEquals(finalPath, expectedFinalPath);
     Assert.assertTrue(fs.exists(finalPath));
   }
+
   /**
    * Test formatter.
    *
@@ -356,39 +393,11 @@ public abstract class TestAbstractFileFormatter {
   }
 
   protected LensResultSetMetadata getMockedResultSet() {
-    return new LensResultSetMetadata() {
-
-      @Override
-      public List<ColumnDescriptor> getColumns() {
-        List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
-        columns.add(new ColumnDescriptor(new FieldSchema("firstcol", "int", ""), 0));
-        columns.add(new ColumnDescriptor(new FieldSchema("format(secondcol,2)", "string", ""), 1));
-        columns.add(new ColumnDescriptor(new FieldSchema("thirdcol", "varchar(20)", ""), 2));
-        columns.add(new ColumnDescriptor(new FieldSchema("fourthcol", "char(15)", ""), 3));
-        columns.add(new ColumnDescriptor(new FieldSchema("fifthcol", "array<tinyint>", ""), 4));
-        columns.add(new ColumnDescriptor(new FieldSchema("sixthcol", "struct<a:int,b:varchar(10)>", ""), 5));
-        columns.add(new ColumnDescriptor(new FieldSchema("seventhcol", "map<int,char(10)>", ""), 6));
-        return columns;
-      }
-    };
+    return MockLensResultSetMetadata.createMockedResultSet();
   }
 
   protected LensResultSetMetadata getMockedResultSetWithoutComma() {
-    return new LensResultSetMetadata() {
-
-      @Override
-      public List<ColumnDescriptor> getColumns() {
-        List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
-        columns.add(new ColumnDescriptor(new FieldSchema("firstcol", "int", ""), 0));
-        columns.add(new ColumnDescriptor(new FieldSchema("secondcol", "string", ""), 1));
-        columns.add(new ColumnDescriptor(new FieldSchema("thirdcol", "varchar(20)", ""), 2));
-        columns.add(new ColumnDescriptor(new FieldSchema("fourthcol", "char(15)", ""), 3));
-        columns.add(new ColumnDescriptor(new FieldSchema("fifthcol", "array<tinyint>", ""), 4));
-        columns.add(new ColumnDescriptor(new FieldSchema("sixthcol", "struct<a:int,b:varchar(10)>", ""), 5));
-        columns.add(new ColumnDescriptor(new FieldSchema("seventhcol", "map<int,char(10)>", ""), 6));
-        return columns;
-      }
-    };
+    return MockLensResultSetMetadata.createMockedResultSetWithoutComma();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSetMetadata.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSetMetadata.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSetMetadata.java
index ef8aeed..da90e0a 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSetMetadata.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/LensResultSetMetadata.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.server.api.driver;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -30,11 +31,51 @@ import org.apache.hadoop.hive.serde2.typeinfo.VarcharTypeInfo;
 import org.apache.hive.service.cli.ColumnDescriptor;
 import org.apache.hive.service.cli.TypeDescriptor;
 
+import org.codehaus.jackson.*;
+import org.codehaus.jackson.annotate.JsonTypeInfo;
+import org.codehaus.jackson.map.*;
+import org.codehaus.jackson.map.module.SimpleModule;
+
 /**
  * The Class LensResultSetMetadata.
  */
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
 public abstract class LensResultSetMetadata {
 
+  protected static final ObjectMapper MAPPER;
+
+  /**
+   * Registering custom serializer
+   */
+  static {
+    MAPPER = new ObjectMapper();
+    SimpleModule module = new SimpleModule("HiveColumnModule", new Version(1, 0, 0, null));
+    module.addSerializer(ColumnDescriptor.class, new JsonSerializer<ColumnDescriptor>() {
+      @Override
+      public void serialize(ColumnDescriptor columnDescriptor, JsonGenerator jsonGenerator,
+                            SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+        jsonGenerator.writeStartObject();
+        jsonGenerator.writeStringField("name", columnDescriptor.getName());
+        jsonGenerator.writeStringField("comment", columnDescriptor.getComment());
+        jsonGenerator.writeNumberField("position", columnDescriptor.getOrdinalPosition());
+        jsonGenerator.writeStringField("type", columnDescriptor.getType().getName());
+        jsonGenerator.writeEndObject();
+      }
+    });
+    module.addDeserializer(ColumnDescriptor.class, new JsonDeserializer<ColumnDescriptor>() {
+      @Override
+      public ColumnDescriptor deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
+        throws IOException {
+        ObjectCodec oc = jsonParser.getCodec();
+        JsonNode node = oc.readTree(jsonParser);
+        org.apache.hive.service.cli.Type t = org.apache.hive.service.cli.Type.getType(node.get("type").asText());
+        return new ColumnDescriptor(node.get("name").asText(), node.get("comment").asText(), new TypeDescriptor(t),
+          node.get("position").asInt());
+      }
+    });
+    MAPPER.registerModule(module);
+  }
+
   public abstract List<ColumnDescriptor> getColumns();
 
   /**
@@ -79,4 +120,12 @@ public abstract class LensResultSetMetadata {
     }
     return typeDesc.getTypeName().toLowerCase();
   }
+
+  public static LensResultSetMetadata fromJson(String json) throws IOException {
+    return MAPPER.readValue(json, LensResultSetMetadata.class);
+  }
+
+  public String toJson() throws IOException {
+    return MAPPER.writeValueAsString(this);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index bed79ac..3a5b887 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -145,7 +145,7 @@ public class QueryContext extends AbstractQueryContext {
 
   @Getter
   @Setter
-  private transient QueryOutputFormatter queryOutputFormatter;
+  private QueryOutputFormatter queryOutputFormatter;
 
   /**
    * The finished query persisted.

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryOutputFormatter.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryOutputFormatter.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryOutputFormatter.java
index 0a6cc6b..a165fe9 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryOutputFormatter.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryOutputFormatter.java
@@ -18,6 +18,7 @@
  */
 package org.apache.lens.server.api.query;
 
+import java.io.Externalizable;
 import java.io.IOException;
 
 import org.apache.lens.server.api.driver.LensResultSetMetadata;
@@ -28,7 +29,7 @@ import org.apache.lens.server.api.driver.LensResultSetMetadata;
  * This is an abstract interface, user should implement {@link InMemoryOutputFormatter} or
  * {@link PersistedOutputFormatter} for formatting the result.
  */
-public interface QueryOutputFormatter {
+public interface QueryOutputFormatter extends Externalizable {
 
   /**
    * Initialize the formatter.

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java b/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
index 1e9a182..3f24343 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/LensPersistentResult.java
@@ -32,8 +32,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 
-import org.codehaus.jackson.map.ObjectMapper;
-
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 
@@ -86,10 +84,10 @@ public class LensPersistentResult extends PersistentResultSet {
       ctx.getQueryOutputFormatter().getFileSize(), conf);
   }
 
-  public LensPersistentResult(FinishedLensQuery query, Configuration conf, ObjectMapper mapper) throws
+  public LensPersistentResult(FinishedLensQuery query, Configuration conf) throws
     ClassNotFoundException, IOException {
     this(QueryHandle.fromString(query.getHandle()),
-      mapper.readValue(query.getMetadata(), (Class<LensResultSetMetadata>) Class.forName(query.getMetadataClass())),
+      LensResultSetMetadata.fromJson(query.getMetadata()),
       query.getResult(), query.getRows(), query.getFileSize(), conf);
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/5bae273e/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 3bc9a4a..ea19742 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -79,12 +79,7 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hive.service.cli.CLIService;
-import org.apache.hive.service.cli.ColumnDescriptor;
-import org.apache.hive.service.cli.TypeDescriptor;
 
-import org.codehaus.jackson.*;
-import org.codehaus.jackson.map.*;
-import org.codehaus.jackson.map.module.SimpleModule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -138,11 +133,6 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public static final String NAME = "query";
 
   /**
-   * The Constant MAPPER.
-   */
-  private static final ObjectMapper MAPPER = new ObjectMapper();
-
-  /**
    * The accepted queries.
    */
   private FairPriorityBlockingQueue<QueryContext> queuedQueries
@@ -918,7 +908,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
                         Integer rows = set.size();
                         finishedQuery.setMetadataClass(metadata.getClass().getName());
                         finishedQuery.setResult(outputPath);
-                        finishedQuery.setMetadata(MAPPER.writeValueAsString(metadata));
+                        finishedQuery.setMetadata(metadata.toJson());
                         finishedQuery.setRows(rows);
                         finishedQuery.setFileSize(fileSize);
                       }
@@ -1063,31 +1053,6 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     } catch (Exception e) {
       log.warn("Unable to create finished query table, query purger will not purge queries", e);
     }
-    SimpleModule module = new SimpleModule("HiveColumnModule", new Version(1, 0, 0, null));
-    module.addSerializer(ColumnDescriptor.class, new JsonSerializer<ColumnDescriptor>() {
-      @Override
-      public void serialize(ColumnDescriptor columnDescriptor, JsonGenerator jsonGenerator,
-        SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
-        jsonGenerator.writeStartObject();
-        jsonGenerator.writeStringField("name", columnDescriptor.getName());
-        jsonGenerator.writeStringField("comment", columnDescriptor.getComment());
-        jsonGenerator.writeNumberField("position", columnDescriptor.getOrdinalPosition());
-        jsonGenerator.writeStringField("type", columnDescriptor.getType().getName());
-        jsonGenerator.writeEndObject();
-      }
-    });
-    module.addDeserializer(ColumnDescriptor.class, new JsonDeserializer<ColumnDescriptor>() {
-      @Override
-      public ColumnDescriptor deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
-        throws IOException, JsonProcessingException {
-        ObjectCodec oc = jsonParser.getCodec();
-        JsonNode node = oc.readTree(jsonParser);
-        org.apache.hive.service.cli.Type t = org.apache.hive.service.cli.Type.getType(node.get("type").asText());
-        return new ColumnDescriptor(node.get("name").asText(), node.get("comment").asText(), new TypeDescriptor(t),
-          node.get("position").asInt());
-      }
-    });
-    MAPPER.registerModule(module);
   }
 
   /*
@@ -1423,7 +1388,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
         throw new NotFoundException("InMemory Query result purged " + queryHandle);
       }
       try {
-        return new LensPersistentResult(query, conf, MAPPER);
+        return new LensPersistentResult(query, conf);
       } catch (Exception e) {
         throw new LensException(e);
       }


[25/50] [abbrv] lens git commit: LENS-775 : NPE on closing HadoopFileFormatter

Posted by ra...@apache.org.
LENS-775 : NPE on closing HadoopFileFormatter


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

Branch: refs/heads/current-release-line
Commit: f4c6c11e9637107a63493b98e3bb7d50966e52c1
Parents: 3862c38
Author: Deepak Barr <de...@gmail.com>
Authored: Thu Sep 17 19:12:17 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Thu Sep 17 19:12:17 2015 +0530

----------------------------------------------------------------------
 .../main/java/org/apache/lens/lib/query/HadoopFileFormatter.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/f4c6c11e/lens-query-lib/src/main/java/org/apache/lens/lib/query/HadoopFileFormatter.java
----------------------------------------------------------------------
diff --git a/lens-query-lib/src/main/java/org/apache/lens/lib/query/HadoopFileFormatter.java b/lens-query-lib/src/main/java/org/apache/lens/lib/query/HadoopFileFormatter.java
index 87aff69..d556fb0 100644
--- a/lens-query-lib/src/main/java/org/apache/lens/lib/query/HadoopFileFormatter.java
+++ b/lens-query-lib/src/main/java/org/apache/lens/lib/query/HadoopFileFormatter.java
@@ -135,7 +135,9 @@ public class HadoopFileFormatter extends AbstractFileFormatter {
    */
   @Override
   public void close() throws IOException {
-    rowWriter.close(Reporter.NULL);
+    if (null != rowWriter) {
+      rowWriter.close(Reporter.NULL);
+    }
   }
 
   @Override


[38/50] [abbrv] lens git commit: LENS-795 : Look ahead is failing with partition not found if any process time partitions are absent

Posted by ra...@apache.org.
LENS-795 : Look ahead is failing with partition not found if any process time partitions are absent


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

Branch: refs/heads/current-release-line
Commit: d7f09ede37e1f2d75e3e3d62a2e3a0a2375575cc
Parents: e5b793c
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Wed Sep 30 19:17:26 2015 +0530
Committer: Raju Bairishetti <ra...@im0933-x0.corp.inmobi.com>
Committed: Wed Sep 30 19:17:26 2015 +0530

----------------------------------------------------------------------
 .../PartitionRangesForPartitionColumns.java      |  6 ++++--
 .../lens/cube/parse/StorageTableResolver.java    | 19 +++++++++++++++----
 2 files changed, 19 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/d7f09ede/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
index b389a8f..fa3f6ef 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
@@ -41,10 +41,12 @@ public class PartitionRangesForPartitionColumns extends HashMap<String, RangesPa
       .rangeUpto(partition.next().withUpdatePeriod(UpdatePeriod.values()[0])));
   }
 
-  public Set<String> toSet() {
+  public Set<String> toSet(Set<String> partColsQueried) {
     Set<String> ret = Sets.newHashSet();
     for (Map.Entry<String, RangesPartitionTimeline> entry : entrySet()) {
-      ret.add(entry.getKey() + ":" + entry.getValue().getRanges());
+      if (partColsQueried.contains(entry.getKey())) {
+        ret.add(entry.getKey() + ":" + entry.getValue().getRanges());
+      }
     }
     return ret;
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/d7f09ede/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
index 68ab5ab..f67fc26 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
@@ -363,7 +363,9 @@ class StorageTableResolver implements ContextRewriter {
       PartitionRangesForPartitionColumns missingParts = new PartitionRangesForPartitionColumns();
       boolean noPartsForRange = false;
       Set<String> unsupportedTimeDims = Sets.newHashSet();
+      Set<String> partColsQueried = Sets.newHashSet();
       for (TimeRange range : cubeql.getTimeRanges()) {
+        partColsQueried.add(range.getPartitionColumn());
         StringBuilder extraWhereClause = new StringBuilder();
         Set<FactPartition> rangeParts = getPartitions(cfact.fact, range, skipStorageCauses, missingParts);
         // If no partitions were found, then we'll fallback.
@@ -389,6 +391,7 @@ class StorageTableResolver implements ContextRewriter {
           if (fallBackRange == null) {
             break;
           }
+          partColsQueried.add(fallBackRange.getPartitionColumn());
           rangeParts = getPartitions(cfact.fact, fallBackRange, skipStorageCauses, missingParts);
           extraWhereClause.append(sep)
             .append(prevRange.toTimeDimWhereClause(cubeql.getAliasForTableName(cubeql.getCube()), timeDim));
@@ -433,7 +436,7 @@ class StorageTableResolver implements ContextRewriter {
         i.remove();
         continue;
       }
-      Set<String> nonExistingParts = missingParts.toSet();
+      Set<String> nonExistingParts = missingParts.toSet(partColsQueried);
       if (!nonExistingParts.isEmpty()) {
         addNonExistingParts(cfact.fact.getName(), nonExistingParts);
       }
@@ -637,8 +640,10 @@ class StorageTableResolver implements ContextRewriter {
                   for (Date date : timeRange.iterable(pPart.getPeriod(), 1)) {
                     FactPartition innerPart = new FactPartition(partCol, date, pPart.getPeriod(), pPart,
                       partWhereClauseFormat);
-                    updateFactPartitionStorageTablesFrom(fact, innerPart, pPart.getStorageTables());
-                    partitions.add(innerPart);
+                    updateFactPartitionStorageTablesFrom(fact, innerPart, pPart);
+                    if (innerPart.isFound()) {
+                      partitions.add(innerPart);
+                    }
                   }
                   log.debug("added all sub partitions blindly in pPart: {}", pPart);
                 }
@@ -678,7 +683,7 @@ class StorageTableResolver implements ContextRewriter {
         updatePeriods, addNonExistingParts, failOnPartialData, skipStorageCauses, missingPartitions);
   }
 
-  void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
+  private void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
     FactPartition part, Set<String> storageTableNames) throws LensException, HiveException, ParseException {
     for (String storageTableName : storageTableNames) {
       if (client.factPartitionExists(fact, part, storageTableName)) {
@@ -687,4 +692,10 @@ class StorageTableResolver implements ContextRewriter {
       }
     }
   }
+
+  private void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
+    FactPartition part, FactPartition pPart) throws LensException, HiveException, ParseException {
+    updateFactPartitionStorageTablesFrom(fact, part, pPart.getStorageTables());
+    part.setFound(part.isFound() && pPart.isFound());
+  }
 }


[17/50] [abbrv] lens git commit: LENS-710 : Allow column name mapping for few/all columns in underlying storage tables

Posted by ra...@apache.org.
LENS-710 : Allow column name mapping for few/all columns in underlying storage tables


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/3563aacf
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/3563aacf
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/3563aacf

Branch: refs/heads/current-release-line
Commit: 3563aacf7c41a257d4c306153555099333ed5a47
Parents: 3576207
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Tue Sep 8 21:49:39 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Tue Sep 8 21:49:39 2015 +0530

----------------------------------------------------------------------
 lens-api/src/main/resources/cube-0.1.xsd        |   9 +
 .../lens/driver/jdbc/ColumnarSQLRewriter.java   | 179 ++++++++++++++-----
 .../driver/jdbc/TestColumnarSQLRewriter.java    |  91 +++++++++-
 .../lens/server/api/LensConfConstants.java      |   5 +
 4 files changed, 232 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/3563aacf/lens-api/src/main/resources/cube-0.1.xsd
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/cube-0.1.xsd b/lens-api/src/main/resources/cube-0.1.xsd
index 0a981dd..58f68f5 100644
--- a/lens-api/src/main/resources/cube-0.1.xsd
+++ b/lens-api/src/main/resources/cube-0.1.xsd
@@ -811,6 +811,15 @@
         <xs:annotation>
           <xs:documentation>
             Table properties.
+            The following properties can be specified for DBStorage table :
+            1. lens.metastore.native.db.name : The underlying databse name in DB storage.
+            2. lens.metastore.native.table.name : The underlying table name in DB storage.
+            3. lens.metastore.native.table.column.mapping : The column mapping for columns of the table if they are
+            different in underlying DB storage. The value is specified with comma separated map entries specified with
+            key-values separated by equalto. Example value: id=id1,name=name1
+            The following properties can be specified for Elastic search tables :
+            1. lens.metastore.es.index.name : The underlying ES index name.
+            2. lens.metastore.es.type.name : The underlying ES type name.
           </xs:documentation>
         </xs:annotation>
       </xs:element>

http://git-wip-us.apache.org/repos/asf/lens/blob/3563aacf/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/ColumnarSQLRewriter.java
----------------------------------------------------------------------
diff --git a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/ColumnarSQLRewriter.java b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/ColumnarSQLRewriter.java
index 9ceb9f3..295b476 100644
--- a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/ColumnarSQLRewriter.java
+++ b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/ColumnarSQLRewriter.java
@@ -42,6 +42,8 @@ import org.apache.hadoop.hive.ql.parse.SemanticException;
 
 import org.antlr.runtime.CommonToken;
 
+import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
 /**
@@ -147,24 +149,31 @@ public class ColumnarSQLRewriter implements QueryRewriter {
   private String fromTree;
 
   /** The join ast. */
+  @Getter
   private ASTNode joinAST;
 
   /** The having ast. */
+  @Getter
   private ASTNode havingAST;
 
   /** The select ast. */
+  @Getter
   private ASTNode selectAST;
 
   /** The where ast. */
+  @Getter
   private ASTNode whereAST;
 
   /** The order by ast. */
+  @Getter
   private ASTNode orderByAST;
 
   /** The group by ast. */
+  @Getter
   private ASTNode groupByAST;
 
   /** The from ast. */
+  @Getter
   protected ASTNode fromAST;
 
   /**
@@ -944,7 +953,7 @@ public class ColumnarSQLRewriter implements QueryRewriter {
    */
   public void buildQuery(Configuration conf, HiveConf hconf) throws SemanticException {
     analyzeInternal(conf, hconf);
-    replaceWithUnderlyingStorage(hconf, fromAST);
+    replaceWithUnderlyingStorage(hconf);
     replaceAliasInAST();
     getFilterInJoinCond(fromAST);
     getAggregateColumns(selectAST, new MutableInt(0));
@@ -1187,67 +1196,143 @@ public class ColumnarSQLRewriter implements QueryRewriter {
     return queryReplacedUdf;
   }
 
-  // Replace Lens database names with storage's proper DB and table name based
-  // on table properties.
+
+  @NoArgsConstructor
+  private static class NativeTableInfo {
+    private Map<String, String> columnMapping = new HashMap<>();
+    NativeTableInfo(Table tbl) {
+      String columnMappingProp = tbl.getProperty(LensConfConstants.NATIVE_TABLE_COLUMN_MAPPING);
+      if (StringUtils.isNotBlank(columnMappingProp)) {
+        String[] columnMapArray = StringUtils.split(columnMappingProp, ",");
+        for (String columnMapEntry : columnMapArray) {
+          String[] mapEntry = StringUtils.split(columnMapEntry, "=");
+          columnMapping.put(mapEntry[0].trim(), mapEntry[1].trim());
+        }
+      }
+    }
+    String getNativeColumn(String col) {
+      String retCol = columnMapping.get(col);
+      return retCol != null ? retCol : col;
+    }
+  }
+
+  private Map<String, NativeTableInfo> aliasToNativeTableInfo = new HashMap<>();
 
   /**
    * Replace with underlying storage.
    *
-   * @param tree the AST tree
+   * @param metastoreConf the metastore configuration
    */
-  protected void replaceWithUnderlyingStorage(HiveConf metastoreConf, ASTNode tree) {
+  protected void replaceWithUnderlyingStorage(HiveConf metastoreConf) {
+    replaceDBAndTableNames(metastoreConf, fromAST);
+    if (aliasToNativeTableInfo.isEmpty()) {
+      return;
+    }
+    replaceColumnNames(selectAST);
+    replaceColumnNames(fromAST);
+    replaceColumnNames(whereAST);
+    replaceColumnNames(groupByAST);
+    replaceColumnNames(orderByAST);
+    replaceColumnNames(havingAST);
+  }
+  // Replace Lens database names with storage's proper DB and table name based
+  // on table properties.
+  protected void replaceDBAndTableNames(HiveConf metastoreConf, ASTNode tree) {
     if (tree == null) {
       return;
     }
 
-    if (TOK_TABNAME == tree.getToken().getType()) {
-      // If it has two children, the first one is the DB name and second one is
-      // table identifier
-      // Else, we have to add the DB name as the first child
-      try {
-        if (tree.getChildCount() == 2) {
-          ASTNode dbIdentifier = (ASTNode) tree.getChild(0);
-          ASTNode tableIdentifier = (ASTNode) tree.getChild(1);
-          String lensTable = dbIdentifier.getText() + "." + tableIdentifier.getText();
-          Table tbl = CubeMetastoreClient.getInstance(metastoreConf).getHiveTable(lensTable);
-          String table = getUnderlyingTableName(tbl);
-          String db = getUnderlyingDBName(tbl);
-
-          // Replace both table and db names
-          if ("default".equalsIgnoreCase(db)) {
-            // Remove the db name for this case
-            tree.deleteChild(0);
-          } else if (StringUtils.isNotBlank(db)) {
-            dbIdentifier.getToken().setText(db);
-          } // If db is empty, then leave the tree untouched
-
-          if (StringUtils.isNotBlank(table)) {
-            tableIdentifier.getToken().setText(table);
-          }
-        } else {
-          ASTNode tableIdentifier = (ASTNode) tree.getChild(0);
-          String lensTable = tableIdentifier.getText();
-          Table tbl = CubeMetastoreClient.getInstance(metastoreConf).getHiveTable(lensTable);
-          String table = getUnderlyingTableName(tbl);
-          // Replace table name
-          if (StringUtils.isNotBlank(table)) {
-            tableIdentifier.getToken().setText(table);
-          }
+    if (TOK_TABREF == tree.getToken().getType()) {
+      // TOK_TABREF will have TOK_TABNAME as first child and alias as second child.
+      String alias;
+      String tblName = null;
+      Table tbl = null;
+      ASTNode tabNameChild = (ASTNode) tree.getChild(0);
+      if (TOK_TABNAME == tabNameChild.getToken().getType()) {
+        // If it has two children, the first one is the DB name and second one is
+        // table identifier
+        // Else, we have to add the DB name as the first child
+        try {
+          if (tabNameChild.getChildCount() == 2) {
+            ASTNode dbIdentifier = (ASTNode) tabNameChild.getChild(0);
+            ASTNode tableIdentifier = (ASTNode) tabNameChild.getChild(1);
+            tblName = tableIdentifier.getText();
+            String lensTable = dbIdentifier.getText() + "." + tblName;
+            tbl = CubeMetastoreClient.getInstance(metastoreConf).getHiveTable(lensTable);
+            String table = getUnderlyingTableName(tbl);
+            String db = getUnderlyingDBName(tbl);
+
+            // Replace both table and db names
+            if ("default".equalsIgnoreCase(db)) {
+              // Remove the db name for this case
+              tabNameChild.deleteChild(0);
+            } else if (StringUtils.isNotBlank(db)) {
+              dbIdentifier.getToken().setText(db);
+            } // If db is empty, then leave the tree untouched
+
+            if (StringUtils.isNotBlank(table)) {
+              tableIdentifier.getToken().setText(table);
+            }
+          } else {
+            ASTNode tableIdentifier = (ASTNode) tabNameChild.getChild(0);
+            tblName = tableIdentifier.getText();
+            tbl = CubeMetastoreClient.getInstance(metastoreConf).getHiveTable(tblName);
+            String table = getUnderlyingTableName(tbl);
+            // Replace table name
+            if (StringUtils.isNotBlank(table)) {
+              tableIdentifier.getToken().setText(table);
+            }
 
-          // Add db name as a new child
-          String dbName = getUnderlyingDBName(tbl);
-          if (StringUtils.isNotBlank(dbName) && !"default".equalsIgnoreCase(dbName)) {
-            ASTNode dbIdentifier = new ASTNode(new CommonToken(HiveParser.Identifier, dbName));
-            dbIdentifier.setParent(tree);
-            tree.insertChild(0, dbIdentifier);
+            // Add db name as a new child
+            String dbName = getUnderlyingDBName(tbl);
+            if (StringUtils.isNotBlank(dbName) && !"default".equalsIgnoreCase(dbName)) {
+              ASTNode dbIdentifier = new ASTNode(new CommonToken(HiveParser.Identifier, dbName));
+              dbIdentifier.setParent(tabNameChild);
+              tabNameChild.insertChild(0, dbIdentifier);
+            }
+          }
+        } catch (HiveException e) {
+          log.warn("No corresponding table in metastore:", e);
+        }
+      }
+      if (tree.getChildCount() == 2) {
+        alias = tree.getChild(1).getText();
+      } else {
+        alias = tblName;
+      }
+      if (StringUtils.isNotBlank(alias)) {
+        alias = alias.toLowerCase();
+        if (!aliasToNativeTableInfo.containsKey(alias)) {
+          if (tbl != null) {
+            aliasToNativeTableInfo.put(alias, new NativeTableInfo(tbl));
           }
         }
-      } catch (HiveException e) {
-        log.warn("No corresponding table in metastore:", e);
       }
     } else {
       for (int i = 0; i < tree.getChildCount(); i++) {
-        replaceWithUnderlyingStorage(metastoreConf, (ASTNode) tree.getChild(i));
+        replaceDBAndTableNames(metastoreConf, (ASTNode) tree.getChild(i));
+      }
+    }
+  }
+
+  void replaceColumnNames(ASTNode node) {
+    if (node == null) {
+      return;
+    }
+    int nodeType = node.getToken().getType();
+    if (nodeType == HiveParser.DOT) {
+      ASTNode tabident = HQLParser.findNodeByPath(node, TOK_TABLE_OR_COL, Identifier);
+      ASTNode colIdent = (ASTNode) node.getChild(1);
+      String column = colIdent.getText().toLowerCase();
+      String alias = tabident.getText().toLowerCase();
+      if (aliasToNativeTableInfo.get(alias) != null) {
+        colIdent.getToken().setText(aliasToNativeTableInfo.get(alias).getNativeColumn(column));
+      }
+    } else {
+      // recurse down
+      for (int i = 0; i < node.getChildCount(); i++) {
+        ASTNode child = (ASTNode) node.getChild(i);
+        replaceColumnNames(child);
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/3563aacf/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestColumnarSQLRewriter.java
----------------------------------------------------------------------
diff --git a/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestColumnarSQLRewriter.java b/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestColumnarSQLRewriter.java
index 3415a1e..db09a4b 100644
--- a/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestColumnarSQLRewriter.java
+++ b/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestColumnarSQLRewriter.java
@@ -886,7 +886,7 @@ public class TestColumnarSQLRewriter {
     System.out.println(joinTreeBeforeRewrite);
 
     // Rewrite
-    rewriter.replaceWithUnderlyingStorage(hconf, rewriter.fromAST);
+    rewriter.replaceWithUnderlyingStorage(hconf);
     String joinTreeAfterRewrite = HQLParser.getString(rewriter.fromAST);
     System.out.println("joinTreeAfterRewrite:" + joinTreeAfterRewrite);
 
@@ -914,7 +914,7 @@ public class TestColumnarSQLRewriter {
     System.out.println(joinTreeBeforeRewrite);
 
     // Rewrite
-    rewriter.replaceWithUnderlyingStorage(hconf, rewriter.fromAST);
+    rewriter.replaceWithUnderlyingStorage(hconf);
     joinTreeAfterRewrite = HQLParser.getString(rewriter.fromAST);
     System.out.println(joinTreeAfterRewrite);
 
@@ -933,7 +933,7 @@ public class TestColumnarSQLRewriter {
     rewriter.query = defaultQuery;
     rewriter.analyzeInternal(conf, hconf);
     joinTreeBeforeRewrite = HQLParser.getString(rewriter.fromAST);
-    rewriter.replaceWithUnderlyingStorage(hconf, rewriter.fromAST);
+    rewriter.replaceWithUnderlyingStorage(hconf);
     joinTreeAfterRewrite = HQLParser.getString(rewriter.fromAST);
     assertTrue(joinTreeBeforeRewrite.contains("examples"), joinTreeBeforeRewrite);
     assertFalse(joinTreeAfterRewrite.contains("examples"), joinTreeAfterRewrite);
@@ -949,23 +949,104 @@ public class TestColumnarSQLRewriter {
   }
 
   /**
+   * Test replace column mapping.
+   *
+   * @throws Exception the exception
+   */
+  @Test
+  public void testReplaceColumnMapping() throws Exception {
+    SessionState.start(hconf);
+    String testDB = "testrcm";
+
+    // Create test table
+    Database database = new Database();
+    database.setName(testDB);
+
+    Hive.get(hconf).createDatabase(database);
+    try {
+      SessionState.get().setCurrentDatabase(testDB);
+      Map<String, String> columnMap = new HashMap<>();
+      columnMap.put("id", "id1");
+      columnMap.put("name", "name1");
+      createTable(hconf, testDB, "mytable", "testDB", "testTable_1", false, columnMap);
+      columnMap.put("id", "id2");
+      columnMap.put("name", "name2");
+      createTable(hconf, testDB, "mytable_2", "testDB", "testTable_2", false, columnMap);
+      columnMap.put("id", "id3");
+      columnMap.put("name", "name3");
+      createTable(hconf, "default", "mytable_3", "testDB", "testTable_3", false, columnMap);
+
+      String query = "SELECT t1.id, t2.id, t3.id, t1.name, t2.name, t3.name, count(1) FROM " + testDB
+        + ".mytable t1 JOIN mytable_2 t2 ON t1.t2id = t2.id   left outer join default.mytable_3 t3 on t2.t3id = t3.id"
+        + " WHERE t1.id = 100 GROUP BY t2.id HAVING count(t1.id) > 2 ORDER BY t3.id";
+
+      ColumnarSQLRewriter rewriter = new ColumnarSQLRewriter();
+      rewriter.init(conf);
+      rewriter.ast = HQLParser.parseHQL(query, hconf);
+      rewriter.query = query;
+      rewriter.analyzeInternal(conf, hconf);
+
+      // Rewrite
+      rewriter.replaceWithUnderlyingStorage(hconf);
+      String fromStringAfterRewrite = HQLParser.getString(rewriter.fromAST);
+      log.info("fromStringAfterRewrite:{}", fromStringAfterRewrite);
+
+      assertEquals(HQLParser.getString(rewriter.getSelectAST()).trim(), "( t1 . id1 ), ( t2 . id2 ), ( t3 . id3 ),"
+        + " ( t1 . name1 ), ( t2 . name2 ), ( t3 . name3 ), count( 1 )",
+        "Found :" + HQLParser.getString(rewriter.getSelectAST()));
+      assertEquals(HQLParser.getString(rewriter.getWhereAST()).trim(), "(( t1 . id1 ) =  100 )",
+        "Found: " + HQLParser.getString(rewriter.getWhereAST()));
+      assertEquals(HQLParser.getString(rewriter.getGroupByAST()).trim(), "( t2 . id2 )",
+        "Found: " + HQLParser.getString(rewriter.getGroupByAST()));
+      assertEquals(HQLParser.getString(rewriter.getOrderByAST()).trim(), "t3 . id3   asc",
+        "Found: " + HQLParser.getString(rewriter.getOrderByAST()));
+      assertEquals(HQLParser.getString(rewriter.getHavingAST()).trim(), "(count(( t1 . id1 )) >  2 )",
+        "Found: " + HQLParser.getString(rewriter.getHavingAST()));
+      assertTrue(fromStringAfterRewrite.contains("( t1 . t2id ) = ( t2 . id2 )")
+        && fromStringAfterRewrite.contains("( t2 . t3id ) = ( t3 . id3 )"), fromStringAfterRewrite);
+      assertFalse(fromStringAfterRewrite.contains(testDB), fromStringAfterRewrite);
+      assertTrue(fromStringAfterRewrite.contains("testdb"), fromStringAfterRewrite);
+      assertTrue(fromStringAfterRewrite.contains("testtable_1") && fromStringAfterRewrite.contains("testtable_2")
+        && fromStringAfterRewrite.contains("testtable_3"), fromStringAfterRewrite);
+    } finally {
+      Hive.get().dropTable("default", "mytable_3", true, true);
+      Hive.get().dropDatabase(testDB, true, true, true);
+      SessionState.get().setCurrentDatabase("default");
+    }
+  }
+
+  void createTable(HiveConf conf, String db, String table, String udb, String utable) throws Exception {
+    createTable(conf, db, table, udb, utable, true, null);
+  }
+
+  /**
    * Creates the table.
    *
    * @param db     the db
    * @param table  the table
    * @param udb    the udb
    * @param utable the utable
+   * @param setCustomSerde whether to set custom serde or not
+   * @param columnMapping columnmapping for the table
+   *
    * @throws Exception the exception
    */
-  void createTable(HiveConf conf, String db, String table, String udb, String utable) throws Exception {
+  void createTable(HiveConf conf, String db, String table, String udb, String utable, boolean setCustomSerde,
+    Map<String, String> columnMapping) throws Exception {
     Table tbl1 = new Table(db, table);
-    tbl1.setSerializationLib("DatabaseJarSerde");
+    if (setCustomSerde) {
+      tbl1.setSerializationLib("DatabaseJarSerde");
+    }
     if (StringUtils.isNotBlank(udb)) {
       tbl1.setProperty(LensConfConstants.NATIVE_DB_NAME, udb);
     }
     if (StringUtils.isNotBlank(utable)) {
       tbl1.setProperty(LensConfConstants.NATIVE_TABLE_NAME, utable);
     }
+    if (columnMapping != null && !columnMapping.isEmpty()) {
+      tbl1.setProperty(LensConfConstants.NATIVE_TABLE_COLUMN_MAPPING, StringUtils.join(columnMapping.entrySet(), ","));
+      log.info("columnMapping property:{}", tbl1.getProperty(LensConfConstants.NATIVE_TABLE_COLUMN_MAPPING));
+    }
 
     List<FieldSchema> columns = new ArrayList<FieldSchema>();
     columns.add(new FieldSchema("id", "int", "col1"));

http://git-wip-us.apache.org/repos/asf/lens/blob/3563aacf/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index 720825a..fb11f93 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -403,6 +403,11 @@ public final class LensConfConstants {
   public static final String NATIVE_TABLE_NAME = METASTORE_PFX + "native.table.name";
 
   /**
+   * The property name for setting the column mapping, if column names in native table are different
+   */
+  public static final String NATIVE_TABLE_COLUMN_MAPPING = METASTORE_PFX + "native.table.column.mapping";
+
+  /**
    * The Constant ES_INDEX_NAME.
    */
   public static final String ES_INDEX_NAME = METASTORE_PFX + "es.index.name";


[16/50] [abbrv] lens git commit: LENS-737 : Throw single error out with LensMultiException: Add a missing class in the earlier patch

Posted by ra...@apache.org.
LENS-737 : Throw single error out with LensMultiException:   Add a missing class in the earlier patch


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/3576207a
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/3576207a
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/3576207a

Branch: refs/heads/current-release-line
Commit: 3576207a1f2aeba096fe4d60a0c279da133a2706
Parents: ab74f6e
Author: Sushil Mohanty <su...@inmobi.com>
Authored: Tue Sep 8 12:23:20 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Tue Sep 8 12:23:20 2015 +0530

----------------------------------------------------------------------
 .../apache/lens/server/api/LensErrorInfo.java   | 34 ++++++++++++++++++++
 1 file changed, 34 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/3576207a/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
new file mode 100644
index 0000000..449120d
--- /dev/null
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensErrorInfo.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.lens.server.api;
+
+import lombok.*;
+
+@AllArgsConstructor
+public class LensErrorInfo {
+
+  @Getter
+  private int errorCode;
+  @Getter
+  private int errorWeight;
+  @Getter
+  private String errorName;
+
+}


[32/50] [abbrv] lens git commit: LENS-629 : A new improved web client for Lens

Posted by ra...@apache.org.
LENS-629 : A new improved web client for Lens


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/66f164b4
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/66f164b4
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/66f164b4

Branch: refs/heads/current-release-line
Commit: 66f164b476ff316990435a9ea0c9cae36cbf383f
Parents: 669e872
Author: Ankeet Maini <an...@gmail.com>
Authored: Wed Sep 23 14:41:45 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Wed Sep 23 14:41:45 2015 +0530

----------------------------------------------------------------------
 .gitignore                                      |   5 +
 lens-ui/LICENSE                                 | 201 +++++++++++++
 lens-ui/README.markdown                         |  85 ++++++
 lens-ui/app/actions/AdhocQueryActions.js        | 213 ++++++++++++++
 lens-ui/app/actions/LoginActions.js             |  51 ++++
 lens-ui/app/adapters/AdhocQueryAdapter.js       | 157 +++++++++++
 lens-ui/app/adapters/AuthenticationAdapter.js   |  55 ++++
 lens-ui/app/adapters/BaseAdapter.js             |  90 ++++++
 lens-ui/app/app.js                              |  58 ++++
 lens-ui/app/components/AboutComponent.js        |  33 +++
 lens-ui/app/components/AdhocQueryComponent.js   |  74 +++++
 lens-ui/app/components/AppComponent.js          |  40 +++
 lens-ui/app/components/CubeSchemaComponent.js   | 196 +++++++++++++
 lens-ui/app/components/CubeTreeComponent.js     | 175 ++++++++++++
 lens-ui/app/components/DatabaseComponent.js     | 127 +++++++++
 lens-ui/app/components/HeaderComponent.js       |  90 ++++++
 lens-ui/app/components/LoaderComponent.js       |  34 +++
 lens-ui/app/components/LoginComponent.js        | 109 +++++++
 lens-ui/app/components/LogoutComponent.js       |  42 +++
 lens-ui/app/components/QueryBoxComponent.js     | 282 +++++++++++++++++++
 .../components/QueryDetailResultComponent.js    | 192 +++++++++++++
 .../app/components/QueryOperationsComponent.js  |  87 ++++++
 lens-ui/app/components/QueryPreviewComponent.js | 176 ++++++++++++
 lens-ui/app/components/QueryResultsComponent.js | 123 ++++++++
 .../RequireAuthenticationComponent.js           |  37 +++
 lens-ui/app/components/SidebarComponent.js      |  38 +++
 lens-ui/app/components/TableSchemaComponent.js  | 131 +++++++++
 lens-ui/app/components/TableTreeComponent.js    | 238 ++++++++++++++++
 lens-ui/app/constants/AdhocQueryConstants.js    |  51 ++++
 lens-ui/app/constants/AppConstants.js           |  27 ++
 lens-ui/app/dispatcher/AppDispatcher.js         |  15 +
 lens-ui/app/stores/AdhocQueryStore.js           | 138 +++++++++
 lens-ui/app/stores/CubeStore.js                 |  84 ++++++
 lens-ui/app/stores/DatabaseStore.js             |  62 ++++
 lens-ui/app/stores/TableStore.js                | 102 +++++++
 lens-ui/app/stores/UserStore.js                 | 132 +++++++++
 lens-ui/app/styles/css/global.css               |  18 ++
 lens-ui/app/styles/css/login.css                |  57 ++++
 lens-ui/app/styles/css/query-component.css      |  34 +++
 lens-ui/app/styles/css/tree.css                 |  51 ++++
 lens-ui/app/styles/less/globals.less            |  23 ++
 lens-ui/config.json                             |   4 +
 lens-ui/index.html                              | 100 +++++++
 lens-ui/package.json                            |  51 ++++
 lens-ui/pom.xml                                 |  79 ++++++
 lens-ui/server.js                               |  79 ++++++
 lens-ui/webpack.config.js                       |  55 ++++
 pom.xml                                         |   9 +
 48 files changed, 4310 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 5a356e0..aca87dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,8 @@ test-output/
 #Other
 bin/
 out/
+
+build/
+assets/
+node/
+node_modules/

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/LICENSE
----------------------------------------------------------------------
diff --git a/lens-ui/LICENSE b/lens-ui/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/lens-ui/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/README.markdown
----------------------------------------------------------------------
diff --git a/lens-ui/README.markdown b/lens-ui/README.markdown
new file mode 100644
index 0000000..98fc79e
--- /dev/null
+++ b/lens-ui/README.markdown
@@ -0,0 +1,85 @@
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+
+
+
+# LENS UI #
+
+This app is a front end client for Apache LENS server.
+- It lets you fire queries.
+- Discover cubes, its measures and dimensions.
+
+# Running #
+
+## Using Node Express Server ##
+- add your LENS Server address in **package.json** under `scripts` *start* and *dev* to `lensserver` argument, this is the value of `lens.server.base.url` property of your LENS installation
+- default port is 8082, if you'd like to change it please change the *port* argument in **package.json** under `scripts` *start* or *dev*
+- doing ```npm run dev``` starts the UI in dev mode, with the JavaScript assets in a non-minified way which help in debugging, also it'll be watching to the changes in the source and would generate the new assets automatically.
+- doing ```npm run start``` will minify and uglifiy the assets.
+
+```bash
+cd lens-ui
+npm run start
+```
+
+- point chrome to [http://localhost:8082](http://localhost:8082)
+
+## Using any other server ##
+
+```bash
+cd lens-ui
+npm install
+node_modules/webpack/bin/webpack
+```
+- you now have built assets in `assets` directory
+- add LENS server address *(lens.server.base.url)* in `config.json` file in `baseURL`
+- run your server, e.g python
+
+```bash
+python -m SimpleHTTPServer
+```
+- this will serve the `index.html` present at the root.
+- this will cause your browser to make cross domain requests and if you don't have CORS enabled on your server, the app won't be able to get any data from LENS server.
+  - to get around till you enable CORS on server side, open chrome in disabled web security mode.
+  - first, quit chrome completely, then see the following steps to run browsers in disabled security mode
+  - [start chrome in disabled security mode](https://blog.nraboy.com/2014/08/bypass-cors-errors-testing-apis-locally/)
+
+# Code Structure #
+
+- All JavaScript is in app directory.
+
+# Configurations #
+
+- The app can be configured to show either **INMEMORY** or **PERSISTENT** results.
+- The setting can be done by altering a boolean variable present in `config.json`
+  - `isPersistent`: true // results will be available as downloadable files
+  - `isPersistent`: false // results will be shown in table format
+- Any custom headers you wish to add can be added in `config.json` as a property
+  ```javascript
+  "headers": {
+    "Some-Header": "SomeValue",
+    "Another-Header": "AnotherValue"
+  }
+  ```
+
+# Environment #
+
+Built using:-
+
+- React
+- [Facebook's Flux implementation](https://www.npmjs.com/package/flux)
+- [Reqwest](https://www.npmjs.com/package/reqwest) for making ajax calls wrapped with JavaScript promises.

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/actions/AdhocQueryActions.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/actions/AdhocQueryActions.js b/lens-ui/app/actions/AdhocQueryActions.js
new file mode 100644
index 0000000..8c2d109
--- /dev/null
+++ b/lens-ui/app/actions/AdhocQueryActions.js
@@ -0,0 +1,213 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AdhocQueryConstants from '../constants/AdhocQueryConstants';
+import AdhocQueryAdapter from '../adapters/AdhocQueryAdapter';
+
+let AdhocQueryActions = {
+  getDatabases (secretToken) {
+    AdhocQueryAdapter.getDatabases(secretToken)
+      .then(function (databases) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_DATABASES,
+          payload: { databases: databases }
+        });
+      }, function (error) {
+
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_DATABASES_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getCubes (secretToken) {
+    AdhocQueryAdapter.getCubes(secretToken)
+      .then(function (cubes) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_CUBES,
+          payload: { cubes: cubes }
+        });
+      }, function (error) {
+
+        // propagating the error message, couldn't fetch cubes
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_CUBES_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  executeQuery (secretToken, query, queryName) {
+    AdhocQueryAdapter.executeQuery(secretToken, query, queryName)
+      .then(function (queryHandle) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE,
+          payload: { queryHandle: queryHandle }
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_HANDLE_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getCubeDetails (secretToken, cubeName) {
+    AdhocQueryAdapter.getCubeDetails(secretToken, cubeName)
+      .then(function (cubeDetails) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_CUBE_DETAILS,
+          payload: { cubeDetails: cubeDetails }
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_CUBE_DETAILS_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getQueries (secretToken, email, options) {
+    AdhocQueryAdapter.getQueries(secretToken, email, options)
+      .then(function (queries) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERIES,
+          payload: { queries: queries }
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERIES_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getQuery (secretToken, handle) {
+    AdhocQueryAdapter.getQuery(secretToken, handle)
+      .then(function (query) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY,
+          payload: { query: query }
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getQueryResult (secretToken, handle, queryMode) {
+    AdhocQueryAdapter.getQueryResult(secretToken, handle, queryMode)
+      .then(function (result) {
+        let payload;
+        if (Object.prototype.toString.call(result).match('String')) {
+
+          // persistent
+          payload = { downloadURL: result, type: 'PERSISTENT', handle: handle };
+        } else if (Object.prototype.toString.call(result).match('Array')) {
+
+          // in-memory gives array
+          payload = {
+            queryResult: result[0],
+            columns: result[1],
+            handle: handle,
+            type: 'INMEMORY'
+          };
+        }
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_RESULT,
+          payload: payload
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_QUERY_RESULT_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getTables (secretToken, database) {
+    AdhocQueryAdapter.getTables(secretToken, database)
+      .then(function (tables) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_TABLES,
+          payload: { tables: tables, database: database }
+        });
+      }, function (error) {
+
+        // propagating the error message, couldn't fetch cubes
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_TABLES_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  getTableDetails (secretToken, tableName, database) {
+    AdhocQueryAdapter.getTableDetails(secretToken, tableName, database)
+      .then(function (tableDetails) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_TABLE_DETAILS,
+          payload: { tableDetails: tableDetails, database: database }
+        });
+      }, function (error) {
+        AppDispatcher.dispatch({
+          actionType: AdhocQueryConstants.RECEIVE_TABLE_DETAILS_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+  },
+
+  cancelQuery (secretToken, handle) {
+    AdhocQueryAdapter.cancelQuery(secretToken, handle);
+    // TODO finish this up
+  }
+};
+
+export default AdhocQueryActions;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/actions/LoginActions.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/actions/LoginActions.js b/lens-ui/app/actions/LoginActions.js
new file mode 100644
index 0000000..3cb39d0
--- /dev/null
+++ b/lens-ui/app/actions/LoginActions.js
@@ -0,0 +1,51 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import AppDispatcher from '../dispatcher/AppDispatcher';
+import AppConstants from '../constants/AppConstants';
+import AuthenticationAdapter from '../adapters/AuthenticationAdapter';
+
+let LoginActions = {
+  authenticate (email, password) {
+    AuthenticationAdapter.authenticate(email, password)
+      .then(function (response) {
+
+        // authenticating user right away
+        AppDispatcher.dispatch({
+          actionType: AppConstants.AUTHENTICATION_SUCCESS,
+          payload: {
+            email: email,
+            secretToken: response
+          }
+        });
+      }, function (error) {
+
+        // propagating the error message
+        AppDispatcher.dispatch({
+          actionType: AppConstants.AUTHENTICATION_FAILED,
+          payload: {
+            responseCode: error.status,
+            responseMessage: error.statusText
+          }
+        });
+      });
+    }
+};
+
+export default LoginActions;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/adapters/AdhocQueryAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/AdhocQueryAdapter.js b/lens-ui/app/adapters/AdhocQueryAdapter.js
new file mode 100644
index 0000000..98f9b49
--- /dev/null
+++ b/lens-ui/app/adapters/AdhocQueryAdapter.js
@@ -0,0 +1,157 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import Promise from 'bluebird';
+
+import BaseAdapter from './BaseAdapter';
+import Config from 'config.json';
+
+let baseUrl = Config.baseURL;
+let urls = {
+  'getDatabases': 'metastore/databases',
+  'getCubes': 'metastore/cubes',
+  'query': 'queryapi/queries', // POST on this to execute, GET to fetch all
+  'getTables': 'metastore/nativetables'
+};
+
+let AdhocQueryAdapter = {
+  getDatabases (secretToken) {
+    let url = baseUrl + urls.getDatabases;
+    return BaseAdapter.get(url, { sessionid: secretToken });
+  },
+
+  getCubes (secretToken) {
+    let url = baseUrl + urls.getCubes;
+    return BaseAdapter.get(url, { sessionid: secretToken });
+  },
+
+  getCubeDetails (secretToken, cubeName) {
+    let url = baseUrl + urls.getCubes + '/' + cubeName;
+    return BaseAdapter.get(url, { sessionid: secretToken });
+  },
+
+  executeQuery (secretToken, query, queryName) {
+    let url = baseUrl + urls.query;
+
+    let formData = new FormData();
+    formData.append('sessionid', secretToken);
+    formData.append('query', query);
+    formData.append('operation', 'execute');
+
+    if (queryName)  formData.append('queryName', queryName);
+
+    return BaseAdapter.post(url, formData, {
+      contentType: 'multipart/form-data'
+    });
+  },
+
+  getQuery (secretToken, handle) {
+    let url = baseUrl + urls.query + '/' + handle;
+    return BaseAdapter.get(url, {sessionid: secretToken});
+  },
+
+  getQueries (secretToken, email, options) {
+    let url = baseUrl + urls.query;
+
+    let queryOptions = {};
+    queryOptions.sessionid = secretToken;
+    queryOptions.user = email;
+
+    if (options && options.state) {
+      queryOptions.state = options.state.toUpperCase();
+    }
+
+    return BaseAdapter.get(url, queryOptions)
+      .then(function (queryHandles) {
+
+        // FIXME limiting to 10 for now
+        //let handles = queryHandles.slice(0, 10);
+        return Promise.all(queryHandles.map((handle) => {
+          return BaseAdapter.get(url + '/' + handle.handleId, {
+            sessionid: secretToken,
+            queryHandle: handle.handleId
+          });
+        }));
+      });
+  },
+
+  getQueryResult (secretToken, handle, queryMode) {
+
+    // on page refresh, the store won't have queryMode so fetch query
+    // this is needed as we won't know in which mode the query was fired
+    if (!queryMode) {
+      this.getQuery(secretToken, handle).then((query) => {
+        queryMode = query.isPersistent;
+        queryMode = queryMode ? 'PERSISTENT': 'INMEMORY';
+        return this._inMemoryOrPersistent(secretToken, handle, queryMode);
+      });
+    } else {
+      return this._inMemoryOrPersistent(secretToken, handle, queryMode);
+    }
+  },
+
+  // a method used only internally to figure out
+  // whether to fetch INMEMORY or PERSISTENT results
+  _inMemoryOrPersistent (secretToken, handle, queryMode) {
+    return queryMode === 'PERSISTENT' ?
+      this.getDownloadURL(secretToken, handle) :
+      this.getInMemoryResults(secretToken, handle);
+  },
+
+  getTables (secretToken, database) {
+    let url = baseUrl + urls.getTables;
+    return BaseAdapter.get(url, {
+      sessionid: secretToken,
+      dbName: database
+    });
+  },
+
+  getTableDetails (secretToken, tableName, database) {
+    let url = baseUrl + urls.getTables + '/' + database + '.' + tableName;
+    return BaseAdapter.get(url, { sessionid: secretToken });
+  },
+
+  cancelQuery (secretToken, handle) {
+    let url = baseUrl + urls.query + '/' + handle + '?sessionid=' + secretToken;
+    return BaseAdapter.delete(url);
+  },
+
+  getDownloadURL (secretToken, handle) {
+    let downloadURL = baseUrl + urls.query + '/' + handle +
+      '/httpresultset?sessionid=' + secretToken;
+
+    return Promise.resolve(downloadURL);
+  },
+
+  getInMemoryResults (secretToken, handle) {
+    let resultUrl = baseUrl + urls.query + '/' + handle + '/resultset';
+    let results = BaseAdapter.get(resultUrl, {
+      sessionid: secretToken
+    });
+
+    let metaUrl = baseUrl + urls.query + '/' + handle + '/resultsetmetadata';
+    let meta = BaseAdapter.get(metaUrl, {
+      sessionid: secretToken
+    });
+
+    return Promise.all([results, meta]);
+  }
+};
+
+export default AdhocQueryAdapter;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/adapters/AuthenticationAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/AuthenticationAdapter.js b/lens-ui/app/adapters/AuthenticationAdapter.js
new file mode 100644
index 0000000..26a35f3
--- /dev/null
+++ b/lens-ui/app/adapters/AuthenticationAdapter.js
@@ -0,0 +1,55 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import BaseAdapter from './BaseAdapter';
+import Config from 'config.json';
+
+// these are required by lens API. Sad.
+let authUrl = Config.baseURL + 'session';
+let queryMode = Config.isPersistent;
+let sessionconf = `<?xml version="1.0" encoding="UTF-8"?>
+                  <conf>
+                    <properties>
+                      <entry>
+                        <key>lens.query.enable.persistent.resultset</key>
+                        <value>` + queryMode + `</value>
+                       </entry>
+                       <entry>
+                        <key>lens.query.enable.persistent.resultset.indriver</key>
+                        <value>false</value>
+                       </entry>
+                    </properties>
+                  </conf>`;
+
+let AuthenticationAdapter = {
+  authenticate (email, password) {
+
+    // preparing data as API accepts multipart/form-data :(
+    var formData = new FormData();
+    formData.append('username', email);
+    formData.append('password', password);
+    formData.append('sessionconf', sessionconf);
+
+    return BaseAdapter.post(authUrl, formData, {
+      contentType: 'multipart/form-data'
+    });
+  }
+};
+
+export default AuthenticationAdapter;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/adapters/BaseAdapter.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/adapters/BaseAdapter.js b/lens-ui/app/adapters/BaseAdapter.js
new file mode 100644
index 0000000..81b9ddc
--- /dev/null
+++ b/lens-ui/app/adapters/BaseAdapter.js
@@ -0,0 +1,90 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import reqwest from 'reqwest';
+import Promise from 'bluebird';
+
+import Config from 'config.json';
+
+function makeReqwest (url, method, data, options = {}) {
+  let reqwestOptions = {
+    url: url,
+    method: method,
+    contentType: 'application/json',
+    type: 'json',
+    headers: {}
+  };
+
+  if (Config.headers) reqwestOptions.headers = Config.headers;
+
+  // delete Content-Type and add Accept
+  reqwestOptions.headers['Accept'] = 'application/json';
+  delete reqwestOptions.headers['Content-Type'];
+  if (data) reqwestOptions.data = data;
+  if (options.contentType === 'multipart/form-data') {
+    reqwestOptions.processData = false;
+    reqwestOptions.contentType = 'multipart/form-data';
+
+    // because server can't handle JSON response on POST
+    delete reqwestOptions.type;
+    delete reqwestOptions.headers['Accept'];
+  }
+
+  return new Promise ((resolve, reject) => {
+    reqwest(reqwestOptions)
+      .then ((response) => {
+        resolve(response);
+      }, (error) => {
+        reject(error);
+      });
+  });
+}
+
+function deleteRequest (url, dataArray) {
+  return makeReqwest(url, 'delete', dataArray);
+}
+
+function get (url, dataArray, options) {
+  return makeReqwest(url, 'get', dataArray, options);
+}
+
+// TODO need to fix this unused 'options'. What params can it have?
+function postJson (url, data, options = {}) {
+  return makeReqwest(url, 'post', data, {contentType: 'application/json'});
+}
+
+function postFormData (url, data, options = {}) {
+  return makeReqwest(url, 'post', data, options);
+}
+
+let BaseAdapter = {
+  get: get,
+
+  post (url, data, options = {}) {
+    if (options.contentType) {
+      return postFormData(url, data, options);
+    } else {
+      return postJson(url, data, options);
+    }
+  },
+
+  delete: deleteRequest
+};
+
+export default BaseAdapter;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/app.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/app.js b/lens-ui/app/app.js
new file mode 100644
index 0000000..3e389a7
--- /dev/null
+++ b/lens-ui/app/app.js
@@ -0,0 +1,58 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import Router from 'react-router';
+import { DefaultRoute, Route, RouteHandler } from 'react-router';
+
+import About from './components/AboutComponent';
+import App from './components/AppComponent';
+import AdhocQuery from './components/AdhocQueryComponent';
+import Login from './components/LoginComponent';
+import Logout from './components/LogoutComponent';
+import QueryResults from './components/QueryResultsComponent';
+import CubeSchema from './components/CubeSchemaComponent';
+import QueryDetailResult from './components/QueryDetailResultComponent';
+import TableSchema from './components/TableSchemaComponent';
+import LoginActions from './actions/LoginActions';
+
+let routes = (
+  <Route name="app" path="/" handler={App} >
+    <Route name="login" handler={Login}/>
+    <Route name="logout" handler={Logout}/>
+    <Route name="query" path="query" handler={AdhocQuery} >
+      <Route name="results" handler={QueryResults}/>
+      <Route name="result" path="/results/:handle" handler={QueryDetailResult}/>
+      <Route name="cubeschema" path="schema/cube/:cubeName" handler={CubeSchema}/>
+      <Route name="tableschema" path="schema/table/:tableName"
+        handler={TableSchema}/>
+
+    </Route>
+    <Route name="about" handler={About} />
+    <DefaultRoute handler={AdhocQuery} />
+  </Route>
+);
+
+Router.run(routes, Router.HistoryLocation, (Handler) => {
+  React.render(<Handler/>, document.getElementById('app'));
+
+  // and hide the loader which was loading in html while JavaScript
+  // was downloading
+  document.getElementById('loader-no-js').style.display = 'none';
+});

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/AboutComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AboutComponent.js b/lens-ui/app/components/AboutComponent.js
new file mode 100644
index 0000000..c911080
--- /dev/null
+++ b/lens-ui/app/components/AboutComponent.js
@@ -0,0 +1,33 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+class About extends React.Component {
+  render() {
+    return (
+      <div className="jumbotron">
+        <h1>Hey there!</h1>
+        <p>Thanks for stopping by.</p>
+      </div>
+    );
+  }
+}
+
+export default About;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/AdhocQueryComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AdhocQueryComponent.js b/lens-ui/app/components/AdhocQueryComponent.js
new file mode 100644
index 0000000..66ddf75
--- /dev/null
+++ b/lens-ui/app/components/AdhocQueryComponent.js
@@ -0,0 +1,74 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { RouteHandler } from 'react-router';
+
+import QueryBox from './QueryBoxComponent';
+import Sidebar from './SidebarComponent';
+import RequireAuthentication from './RequireAuthenticationComponent';
+
+class AdhocQuery extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {toggleQueryBox: true}; // show box when true, hide on false
+    this.toggleQueryBox = this.toggleQueryBox.bind(this);
+  }
+
+  render() {
+    let toggleButtonClass = this.state.toggleQueryBox ? 'default' : 'primary';
+
+    return (
+      <section className="row">
+        <div className="col-md-4">
+          <Sidebar />
+        </div>
+
+        <div className="col-md-8">
+          <div className="panel panel-default">
+            <div className="panel-heading">
+              <h3 className="panel-title">
+                Compose
+                <button
+                  className={'btn btn-xs pull-right btn-' + toggleButtonClass}
+                  onClick={this.toggleQueryBox}>
+                  {this.state.toggleQueryBox ? 'Hide': 'Show'} Query Box
+                </button>
+              </h3>
+            </div>
+            <div className="panel-body" style={{padding: '0px'}}>
+              <QueryBox toggleQueryBox={this.state.toggleQueryBox} {...this.props}/>
+            </div>
+          </div>
+
+          <RouteHandler toggleQueryBox={this.state.toggleQueryBox}/>
+        </div>
+      </section>
+    );
+  }
+
+  // FIXME persist the state in the URL as well
+  toggleQueryBox () {
+    this.setState({toggleQueryBox: !this.state.toggleQueryBox});
+  }
+};
+
+let AuthenticatedAdhocQuery = RequireAuthentication(AdhocQuery);
+
+export default AuthenticatedAdhocQuery;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/AppComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/AppComponent.js b/lens-ui/app/components/AppComponent.js
new file mode 100644
index 0000000..d7a38f9
--- /dev/null
+++ b/lens-ui/app/components/AppComponent.js
@@ -0,0 +1,40 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { RouteHandler } from 'react-router';
+
+import Header from './HeaderComponent';
+
+export default class AppComponent extends React.Component {
+
+  render() {
+    return (
+      <section>
+        <Header />
+
+        <div className="container-fluid">
+          <RouteHandler />
+        </div>
+      </section>
+    );
+  }
+}
+
+export default AppComponent;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/CubeSchemaComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeSchemaComponent.js b/lens-ui/app/components/CubeSchemaComponent.js
new file mode 100644
index 0000000..593c54a
--- /dev/null
+++ b/lens-ui/app/components/CubeSchemaComponent.js
@@ -0,0 +1,196 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+
+import CubeStore from '../stores/CubeStore';
+import UserStore from '../stores/UserStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import Loader from '../components/LoaderComponent';
+
+function getCubes () {
+  return CubeStore.getCubes();
+}
+
+function constructMeasureTable (cubeName, measures) {
+  let table = measures.map((measure) => {
+    return (
+      <tr key={cubeName + '|' + measure.name}>
+        <td>{ measure.name }</td>
+        <td>{ measure.type }</td>
+        <td>{ measure.default_aggr }</td>
+        <td>{ measure.display_string }</td>
+      </tr>
+    );
+  });
+
+  return (
+    <div class="table-responsive">
+      <table className="table table-striped table-condensed">
+        <caption className="bg-primary text-center">Measures</caption>
+        <thead>
+          <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Default Aggr</th>
+            <th>Description</th>
+          </tr>
+        </thead>
+        <tbody>
+          {table}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+function constructDimensionTable (cubeName, dimensions) {
+  let table = dimensions.map((dimension) => {
+    return (
+      <tr key={cubeName + '|' + dimension.name}>
+        <td>{ dimension.name }</td>
+        <td>{ dimension.type }</td>
+        <td>{ dimension.ref_spec && dimension.ref_spec.chain_ref_column &&
+          dimension.ref_spec.chain_ref_column.dest_table }</td>
+        <td>{ dimension.ref_spec && dimension.ref_spec.chain_ref_column &&
+          dimension.ref_spec.chain_ref_column.ref_col }</td>
+        <td>{ dimension.description }</td>
+      </tr>
+    );
+  });
+
+  return (
+    <div class="table-responsive">
+      <table className="table table-striped">
+        <caption className="bg-primary text-center">Dimensions</caption>
+        <thead>
+          <tr>
+            <th>Name</th>
+            <th>Type</th>
+            <th>Destination Table</th>
+            <th>Column</th>
+            <th>Description</th>
+          </tr>
+        </thead>
+        <tbody>
+          {table}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+// TODO add prop checking.
+class CubeSchema extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {cube: {}};
+    this._onChange = this._onChange.bind(this);
+
+    // firing the action for the first time component is rendered
+    // it won't have a cube in the state.
+    let cubeName = props.params.cubeName;
+    AdhocQueryActions
+      .getCubeDetails(UserStore.getUserDetails().secretToken, cubeName);
+  }
+
+  componentDidMount () {
+    CubeStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    CubeStore.removeChangeListener(this._onChange);
+  }
+
+  componentWillReceiveProps (props) {
+    let cubeName = props.params.cubeName;
+    let cube = getCubes()[cubeName];
+
+    if (cube.isLoaded) {
+      this.setState({ cube: getCubes()[cubeName] });
+      return;
+    }
+
+    AdhocQueryActions
+      .getCubeDetails(UserStore.getUserDetails().secretToken, cubeName);
+
+    // empty the previous state
+    this.setState({ cube: {} });
+
+  }
+
+  render () {
+    let schemaSection;
+
+    // this will be empty if it's the first time so show a loader
+    if (!this.state.cube.isLoaded) {
+      schemaSection = <Loader size="8px" margin="2px" />;
+    } else {
+
+      // if we have cube state
+      let cube = this.state.cube;
+      if (this.props.query.type === 'measures') {
+
+        // show only measures
+        schemaSection = constructMeasureTable(cube.name, cube.measures);
+      } else if (this.props.query.type === 'dimensions') {
+
+        // show only dimensions
+        schemaSection = constructDimensionTable(cube.name, cube.dimensions);
+      } else {
+
+        // show both measures, dimensions
+        schemaSection = (
+          <div>
+            { constructMeasureTable(cube.name, cube.measures) }
+            { constructDimensionTable(cube.name, cube.dimensions) }
+          </div>
+        );
+      }
+    }
+
+    // TODO give max height to panel-body depending upon
+    // whether the query box is visible or not.
+    return (
+
+      <section>
+        <div className="panel panel-default">
+          <div className="panel-heading">
+            <h3 className="panel-title">Schema Details: &nbsp;
+              <strong className="text-primary">
+                 {this.props.params.cubeName}
+              </strong>
+            </h3>
+          </div>
+          <div className="panel-body" style={{overflowY: 'auto',
+            maxHeight: this.props.toggleQueryBox ? '260px': '480px'}}>
+            {schemaSection}
+          </div>
+        </div>
+
+      </section>
+    );
+  }
+
+  _onChange () {
+    this.setState({cube: getCubes()[this.props.params.cubeName]});
+  }
+}
+
+export default CubeSchema;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/CubeTreeComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/CubeTreeComponent.js b/lens-ui/app/components/CubeTreeComponent.js
new file mode 100644
index 0000000..241c12f
--- /dev/null
+++ b/lens-ui/app/components/CubeTreeComponent.js
@@ -0,0 +1,175 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import Alert from 'react-bootstrap';
+import TreeView from 'react-treeview';
+import assign from 'object-assign';
+import { Link } from 'react-router';
+import 'react-treeview/react-treeview.css';
+import ClassNames from 'classnames';
+
+import CubeStore from '../stores/CubeStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import UserStore from '../stores/UserStore';
+import Loader from '../components/LoaderComponent';
+import '../styles/css/tree.css';
+
+function getCubeData () {
+  return {
+    cubes: CubeStore.getCubes()
+  };
+}
+
+class CubeTree extends React.Component {
+  constructor (props) {
+    super(props);
+
+    // setting the initial state, as getInitialState only
+    // comes with React.createClass, using constructor is the new
+    // idiomatic way
+    // https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html
+    this.state = { cubes: [], loading: true, isCollapsed: false };
+
+    // no autobinding with ES6 so doing it manually, see link below
+    // https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
+    this._onChange = this._onChange.bind(this);
+    this.toggle = this.toggle.bind(this);
+
+    // need to fire an action to fetch the cubes from server
+    // can't ask the store as it won't have any at the startup
+    // TODO optimize this, don't fire it everytime.
+    AdhocQueryActions.getCubes(UserStore.getUserDetails().secretToken);
+  }
+
+  componentDidMount () {
+    CubeStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    CubeStore.removeChangeListener(this._onChange);
+  }
+
+  render() {
+
+    // cube tree structure sample
+    // [{
+    //   name: 'Cube-1',
+    //   measures: [{name: 'Measure-1'}, {name: 'Measure-1'}], // optional
+    //   dimensions: [{name: 'Dimension-1'}, {name: 'Dimension-1'}] //optional
+    // }, ...]
+
+    var cubeHash = assign({}, this.state.cubes);
+    var cubeTree = Object.keys(this.state.cubes).map((cubeName, i) => {
+      let cube = cubeHash[cubeName];
+
+      let label = <Link to="cubeschema" params={{cubeName: cubeName}}>
+          <span className="node">{cube.name}</span>
+        </Link>;
+
+      let measureLabel = <Link to="cubeschema" params={{cubeName: cubeName}}
+        query={{type: 'measures'}}>
+          <span className="quiet">Measures</span>
+        </Link>;
+
+      let dimensionLabel = <Link to="cubeschema" params={{cubeName: cubeName}}
+        query={{type: 'dimensions'}}>
+          <span className="quiet">Dimensions</span>
+        </Link>
+      return (
+        <TreeView key={cube.name + '|' + i} nodeLabel={label}
+          defaultCollapsed={true} onClick={this.getDetails.bind(this, cube.name)}>
+
+          <TreeView key={cube.name + '|measures'} nodeLabel={measureLabel}
+            defaultCollapsed={!cube.isLoaded}>
+            { cube.measures ? cube.measures.map(measure => {
+              return (
+                <div key={measure.name} className="treeNode measureNode">
+                  {measure.name} ({measure.default_aggr})
+                </div>
+              );
+            }): null }
+          </TreeView >
+
+          <TreeView key={cube.name + '|dimensions'} nodeLabel={dimensionLabel}
+            defaultCollapsed={!cube.isLoaded}>
+            { cube.dimensions ? cube.dimensions.map(dimension => {
+              return (
+                <div className="treeNode dimensionNode" key={dimension.name}>
+                  {dimension.name}
+                </div>
+              );
+            }): null }
+          </TreeView >
+
+        </TreeView >
+      );
+    });
+
+    if (this.state.loading) cubeTree = <Loader size="4px" margin="2px"/>;
+
+    let collapseClass = ClassNames({
+      'pull-right': true,
+      'glyphicon': true,
+      'glyphicon-chevron-up': !this.state.isCollapsed,
+      'glyphicon-chevron-down': this.state.isCollapsed
+    });
+
+    let panelBodyClassName = ClassNames({
+      'panel-body': true,
+      'hide': this.state.isCollapsed
+    });
+
+    return (
+      <div className="panel panel-default">
+        <div className="panel-heading">
+          <h3 className="panel-title">
+            Cubes
+            <span className={collapseClass} onClick={this.toggle}></span>
+          </h3>
+        </div>
+        <div className={panelBodyClassName} style={{maxHeight: '350px', overflowY: 'auto'}}>
+          {cubeTree}
+        </div>
+      </div>
+    );
+  }
+
+  _onChange () {
+    let state = getCubeData();
+    state.loading = false;
+    this.setState(state);
+  }
+
+  // TODO: check its binding in the onClick method
+  // needs to be investigated
+  // https://facebook.github.io/react/tips/communicate-between-components.html
+  getDetails (cubeName) {
+    if (this.state.cubes[cubeName].isLoaded) return;
+
+    AdhocQueryActions
+      .getCubeDetails(UserStore.getUserDetails().secretToken, cubeName);
+  }
+
+  toggle () {
+    this.setState({isCollapsed: !this.state.isCollapsed});
+  }
+}
+
+export default CubeTree;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/DatabaseComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/DatabaseComponent.js b/lens-ui/app/components/DatabaseComponent.js
new file mode 100644
index 0000000..09ee2eb
--- /dev/null
+++ b/lens-ui/app/components/DatabaseComponent.js
@@ -0,0 +1,127 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import ClassNames from 'classnames';
+
+import DatabaseStore from '../stores/DatabaseStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import UserStore from '../stores/UserStore';
+import Loader from '../components/LoaderComponent';
+import TableTree from './TableTreeComponent';
+
+function getDatabases () {
+  return DatabaseStore.getDatabases();
+}
+
+class DatabaseComponent extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {
+      databases: [],
+      loading: true,
+      isCollapsed: false,
+      selectedDatabase: ''
+    };
+    this._onChange = this._onChange.bind(this);
+    this.toggle = this.toggle.bind(this);
+    this.setDatabase = this.setDatabase.bind(this);
+
+    AdhocQueryActions.getDatabases(UserStore.getUserDetails().secretToken);
+  }
+
+  componentDidMount () {
+    DatabaseStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    DatabaseStore.removeChangeListener(this._onChange);
+  }
+
+  render () {
+    let databaseComponent = null;
+
+    let collapseClass = ClassNames({
+      'pull-right': true,
+      'glyphicon': true,
+      'glyphicon-chevron-up': !this.state.isCollapsed,
+      'glyphicon-chevron-down': this.state.isCollapsed
+    });
+
+    let panelBodyClassName = ClassNames({
+      'panel-body': true,
+      'hide': this.state.isCollapsed
+    });
+
+    databaseComponent = (<div>
+        <label className="control-label" id="db">Select a Database</label>
+        <select className="form-control" id="db" onChange={this.setDatabase}>
+          <option value="">Select</option>
+          {this.state.databases.map(database => {
+            return <option value={database}>{database}</option>;
+          })}
+        </select>
+      </div>);
+
+    if (this.state.loading) {
+      databaseComponent = <Loader size="4px" margin="2px"></Loader>;
+    } else if (!this.state.databases.length) {
+      databaseComponent = (<div className="alert-danger"
+          style={{padding: '8px 5px'}}>
+          <strong>Sorry, we couldn&#39;t find any databases.</strong>
+        </div>);
+    }
+
+    return (
+      <div className="panel panel-default">
+        <div className="panel-heading">
+          <h3 className="panel-title">
+            Tables
+            <span className={collapseClass} onClick={this.toggle}></span>
+          </h3>
+        </div>
+        <div className={panelBodyClassName}>
+          {databaseComponent}
+
+          { this.state.selectedDatabase &&
+            <div>
+              <hr style={{marginTop: '10px', marginBottom: '10px'}}/>
+              <TableTree key={this.state.selectedDatabase}
+                database={this.state.selectedDatabase} />
+            </div>
+          }
+        </div>
+      </div>
+    );
+  }
+
+  _onChange () {
+    this.setState({ databases: getDatabases(), loading: false });
+  }
+
+  toggle () {
+    this.setState({ isCollapsed: !this.state.isCollapsed });
+  }
+
+  setDatabase (event) {
+    this.setState({selectedDatabase: event.target.value});
+  }
+}
+
+export default DatabaseComponent;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/HeaderComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/HeaderComponent.js b/lens-ui/app/components/HeaderComponent.js
new file mode 100644
index 0000000..5ec3397
--- /dev/null
+++ b/lens-ui/app/components/HeaderComponent.js
@@ -0,0 +1,90 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import Router from 'react-router';
+import { Link } from 'react-router';
+
+import Logout from './LogoutComponent';
+import UserStore from '../stores/UserStore';
+import Config from 'config.json';
+
+class Header extends React.Component {
+  constructor () {
+    super();
+    this.state = {userName: null};
+    this._onChange = this._onChange.bind(this);
+  }
+
+  componentDidMount () {
+    UserStore.addChangeListener(this._onChange);
+
+    // this component mounts later and CHANGE_EVENT has elapsed
+    // calling _onChange manually once to refresh the value
+    // FIXME is this wrong?
+    this._onChange();
+  }
+
+  componentWillUnmount () {
+    UserStore.removeChangeListener(this._onChange);
+  }
+
+  render () {
+    return (
+      <nav className="navbar navbar-inverse navbar-static-top">
+        <div className="container">
+          <div className="navbar-header">
+            <button type="button" className="navbar-toggle collapsed"
+                data-toggle="collapse" data-target="#navbar"
+                aria-expanded="false" aria-controls="navbar">
+              <span className="sr-only">Toggle navigation</span>
+              <span className="icon-bar"></span>
+              <span className="icon-bar"></span>
+              <span className="icon-bar"></span>
+            </button>
+            <Link className="navbar-brand" to="app">LENS Query<sup>&beta;</sup></Link>
+          </div>
+          <div id="navbar" className="collapse navbar-collapse">
+            <ul className="nav navbar-nav">
+              <li><Link to="about">About</Link></li>
+            </ul>
+
+            { this.state.userName &&
+              (<ul className="nav navbar-nav navbar-right">
+                <li>
+                  <Link to="logout" className="glyphicon glyphicon-log-out"
+                    title="Logout">
+                    <span> {this.state.userName}</span>
+                  </Link>
+                </li>
+              </ul>)
+            }
+
+          </div>
+        </div>
+      </nav>
+    );
+  }
+
+  _onChange () {
+    this.setState({userName: UserStore.getUserDetails().email});
+  }
+}
+
+export default Header;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/LoaderComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LoaderComponent.js b/lens-ui/app/components/LoaderComponent.js
new file mode 100644
index 0000000..ba11c64
--- /dev/null
+++ b/lens-ui/app/components/LoaderComponent.js
@@ -0,0 +1,34 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { GridLoader } from 'halogen';
+
+// TODO add warnings if size and margin props aren't sent.
+class Loader extends React.Component {
+  render () {
+    return (
+      <section style={{margin: '0 auto', maxWidth: '12%'}}>
+        <GridLoader {...this.props} color="#337ab7"/>
+      </section>
+    );
+  }
+}
+
+export default Loader;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/LoginComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LoginComponent.js b/lens-ui/app/components/LoginComponent.js
new file mode 100644
index 0000000..cf95af9
--- /dev/null
+++ b/lens-ui/app/components/LoginComponent.js
@@ -0,0 +1,109 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import UserStore from '../stores/UserStore';
+import LoginActions from '../actions/LoginActions';
+
+import '../styles/css/login.css';
+
+var error = false;
+
+class Login extends React.Component {
+  constructor (props) {
+    super(props);
+    this.handleSubmit = this.handleSubmit.bind(this);
+    this._onChange = this._onChange.bind(this);
+    this.state = {
+      error: UserStore.isUserLoggedIn()
+    };
+  }
+
+  componentDidMount () {
+    UserStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    UserStore.removeChangeListener(this._onChange);
+  }
+
+  handleSubmit (event) {
+    event.preventDefault();
+    var email = this.refs.email.getDOMNode().value;
+    var pass = this.refs.pass.getDOMNode().value;
+
+    LoginActions.authenticate(email, pass);
+  }
+
+  render () {
+    return (
+      <section class="row" style={{margin: 'auto'}}>
+        <form className="form-signin" onSubmit={this.handleSubmit}>
+          <h2 className="form-signin-heading">Sign in</h2>
+          <label for="inputEmail" className="sr-only">Email address</label>
+          <input ref="email" id="inputEmail" className="form-control"
+            placeholder="Email address" required autofocus/>
+          <label for="inputPassword" className="sr-only">Password</label>
+          <input ref="pass" type="password" id="inputPassword"
+            className="form-control" placeholder="Password" required/>
+          <button className="btn btn-primary btn-block"
+            type="submit">Sign in</button>
+          {this.state.error && (
+            <div className="alert-danger text-center"
+              style={{marginTop: '5px', padding: '0px 3px'}}>
+              <h5>Sorry, authentication failed.</h5>
+              <small>{this.state.errorMessage}</small>
+            </div>
+          )}
+        </form>
+      </section>
+    );
+  }
+
+  _onChange (errorHash) {
+    if (errorHash) {
+      error = true;
+
+      // on error return immediately.
+      // need not go to router for a transition
+      return this.setState({
+        errorMessage: errorHash.responseCode + ': ' +
+          errorHash.responseMessage,
+        error: true
+      });
+    }
+
+    // user is authenticated here
+    var { router } = this.context;
+    var nextPath = router.getCurrentQuery().nextPath;
+
+    if (nextPath) {
+      router.replaceWith(nextPath);
+    } else {
+      router.replaceWith('/about');
+    }
+  }
+
+}
+
+Login.contextTypes = {
+  router: React.PropTypes.func
+};
+
+export default Login;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/LogoutComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/LogoutComponent.js b/lens-ui/app/components/LogoutComponent.js
new file mode 100644
index 0000000..3fc1627
--- /dev/null
+++ b/lens-ui/app/components/LogoutComponent.js
@@ -0,0 +1,42 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import { Link } from 'react-router';
+import Config from 'config.json';
+
+import UserStore from '../stores/UserStore';
+
+class Logout extends React.Component {
+
+  componentDidMount () {
+    UserStore.logout();
+  }
+
+  render () {
+    return (
+      <div className="jumbotron text-center">
+        <h3>You&#39;ve succesfully logged out.</h3>
+        <p><Link to="/">Login</Link> to use this awesome app!</p>
+      </div>
+    );
+  }
+}
+
+export default Logout;

http://git-wip-us.apache.org/repos/asf/lens/blob/66f164b4/lens-ui/app/components/QueryBoxComponent.js
----------------------------------------------------------------------
diff --git a/lens-ui/app/components/QueryBoxComponent.js b/lens-ui/app/components/QueryBoxComponent.js
new file mode 100644
index 0000000..6d5843c
--- /dev/null
+++ b/lens-ui/app/components/QueryBoxComponent.js
@@ -0,0 +1,282 @@
+/**
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import React from 'react';
+import CodeMirror from 'codemirror';
+import 'codemirror/lib/codemirror.css';
+import 'codemirror/addon/edit/matchbrackets.js';
+import 'codemirror/addon/hint/sql-hint.js';
+import 'codemirror/addon/hint/show-hint.css';
+import 'codemirror/addon/hint/show-hint.js';
+import 'codemirror/mode/sql/sql.js';
+
+import UserStore from '../stores/UserStore';
+import AdhocQueryActions from '../actions/AdhocQueryActions';
+import AdhocQueryStore from '../stores/AdhocQueryStore';
+import CubeStore from '../stores/CubeStore';
+import TableStore from '../stores/TableStore';
+import DatabaseStore from '../stores/DatabaseStore';
+import Config from 'config.json';
+import '../styles/css/query-component.css';
+
+// keeping a handle to CodeMirror instance,
+// to be used to retrieve the contents of the editor
+let codeMirror = null;
+
+function setLimit (query) {
+  // since pagination is not enabled on server, limit the query to 1000
+  // check if user has specified existing limit > 1000, change it to 1000
+  // dumb way, checking only last two words for `limit <number>` pattern
+  let temp = query.split(' ');
+  if (temp.slice(-2)[0].toLowerCase() === 'limit') {
+
+    if (temp.slice(-1)[0] > 1000)  temp.splice(-1, 1, 1000);
+    query = temp.join(' ');
+  } else {
+    query += ' limit 1000';
+  }
+
+  return query;
+}
+
+function setCode (code) {
+  if (codeMirror) {
+    codeMirror.setValue(code);
+    codeMirror.focus();
+  }
+}
+
+// used to populate the query box when user wants to edit a query
+// TODO improve this.
+// this takes in the query handle and writes the query
+// used from Edit Query link
+function fetchQuery (props) {
+  if (props.query && props.query.handle) {
+    let query = AdhocQueryStore.getQueries()[props.query.handle];
+
+    if (query) {
+      setCode(query.userQuery);
+    }
+  }
+}
+
+function setupCodeMirror (domNode) {
+
+  // instantiating CodeMirror intance with some properties.
+  codeMirror = CodeMirror.fromTextArea(domNode, {
+    mode: 'text/x-sql',
+    indentWithTabs: true,
+    smartIndent: true,
+    lineNumbers: true,
+    matchBrackets : true,
+    autofocus: true,
+    lineWrapping: true
+  });
+}
+
+function updateAutoComplete () {
+
+  // add autocomplete hints to the query box
+  let hints = {};
+
+  // cubes
+  let cubes = CubeStore.getCubes(); // hashmap
+  Object.keys(cubes).forEach((cubeName) => {
+    let cube = cubes[cubeName];
+    hints[cubeName] = [];
+
+    if (cube.measures && cube.measures.length) {
+      cube.measures.forEach((measure) => {
+        hints[cubeName].push(measure.name);
+      });
+    }
+    if (cube.dimensions && cube.dimensions.length) {
+      cube.dimensions.forEach((dimension) => {
+        hints[cubeName].push(dimension.name);
+      });
+    }
+  });
+
+  //  tables
+  let databases = DatabaseStore.getDatabases() || [];
+  let tables = databases.map(db => {
+    if (TableStore.getTables(db)) {
+      return {
+        database: db,
+        tables: TableStore.getTables(db)
+      }
+    }
+  }).filter(item => { return !!item; }); // filtering undefined items
+
+  tables.forEach(tableObject => {
+    Object.keys(tableObject.tables).forEach(tableName => {
+      let table = tableObject.tables[tableName];
+      let qualifiedName = tableObject.database + '.' + tableName;
+      hints[qualifiedName] = [];
+      hints[tableName] = [];
+
+      if (table.columns && table.columns.length) {
+        table.columns.forEach((col) => {
+          hints[qualifiedName].push(col.name);
+          hints[tableName].push(col.name);
+          hints[col.name] = [];
+        });
+      }
+    });
+  });
+
+  codeMirror.options.hintOptions = { tables: hints };
+}
+
+class QueryBox extends React.Component {
+  constructor (props) {
+    super(props);
+    this.runQuery = this.runQuery.bind(this);
+    this._onChange = this._onChange.bind(this);
+
+    this.state = { querySubmitted: false, isRunQueryDisabled: true };
+  }
+
+  componentDidMount () {
+
+    var editor = this.refs.queryEditor.getDOMNode();
+    setupCodeMirror(editor);
+
+    // disable 'Run Query' button when editor is empty
+    // TODO: debounce this, as it'll happen on every key press. :(
+    codeMirror.on('change', () => {
+      codeMirror.getValue() ?
+        this.state.isRunQueryDisabled = false :
+        this.state.isRunQueryDisabled = true;
+
+      this._onChange();
+    });
+
+    // to remove the previous query's submission notification
+    codeMirror.on('focus', () => {
+      this.state.querySubmitted = false;
+    });
+
+    // add Cmd + Enter to fire runQuery
+    codeMirror.setOption("extraKeys", {
+    'Cmd-Enter': (instance) => {
+      this.runQuery();
+    },
+    'Ctrl-Space': 'autocomplete'
+  });
+
+    AdhocQueryStore.addChangeListener(this._onChange);
+    CubeStore.addChangeListener(this._onChange);
+    TableStore.addChangeListener(this._onChange);
+  }
+
+  componentWillUnmount () {
+    AdhocQueryStore.addChangeListener(this._onChange);
+    CubeStore.addChangeListener(this._onChange);
+    TableStore.addChangeListener(this._onChange);
+  }
+
+  componentWillReceiveProps (props) {
+    fetchQuery(props);
+  }
+
+  render () {
+    let queryBoxClass = this.props.toggleQueryBox ? '': 'hide';
+
+    return (
+      <section className={queryBoxClass}>
+        <div style={{borderBottom: '1px solid #dddddd'}}>
+          <textarea ref="queryEditor"></textarea>
+        </div>
+
+        <div className="row" style={{padding: '6px 8px '}}>
+          <div className="col-lg-4 col-md-4 col-sm-4 col-xs-12">
+            <input type="text" className="form-control"
+              placeholder="Query Name (optional)" ref="queryName"/>
+          </div>
+          <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
+            {this.state.querySubmitted && (
+              <div className="alert alert-info" style={{padding: '5px 4px',
+                marginBottom: '0px'}}>
+                Query has been submitted. Results are on their way!
+              </div>
+            )}
+          </div>
+          <div className="col-lg-2 col-md-2 col-sm-2 col-xs-12">
+            <button className="btn btn-primary responsive"
+              onClick={this.runQuery} disabled={this.state.isRunQueryDisabled}>
+              Run Query
+            </button>
+          </div>
+        </div>
+      </section>
+    );
+  }
+
+  runQuery () {
+    let queryName = this.refs.queryName.getDOMNode().value;
+    let secretToken = UserStore.getUserDetails().secretToken;
+    let query = codeMirror.getValue();
+
+    // set limit if mode is in-memory
+    if (!Config.isPersistent) query = setLimit(query);
+
+    AdhocQueryActions.executeQuery(secretToken, query, queryName);
+
+    // show user the query was posted successfully and empty the queryName
+    this.state.querySubmitted = true;
+    this.refs.queryName.getDOMNode().value = '';
+  }
+
+  _onChange () {
+
+    // renders the detail result component if server
+    // replied with a query handle.
+    // this should ideally happen only when the 'Run Query' button is
+    // clicked, and its action updates the store with query-handle.
+    let handle = AdhocQueryStore.getQueryHandle();
+    if (handle) {
+
+      // clear it else detail result component will be rendered
+      // every time the store emits a change event.
+      AdhocQueryStore.clearQueryHandle();
+
+      var { router } = this.context;
+      router.transitionTo('result', {handle: handle});
+    }
+
+    // TODO remove this.
+    // check if handle was passed as query param, and if that
+    // query was fetched and available in store now.
+    // if (this.props && this.props.query.handle) {
+    //
+    //   let query = AdhocQueryStore.getQueries()[this.props.query.handle];
+    //   if (query)  setCode(query.userQuery);
+    // }
+
+    updateAutoComplete();
+    this.setState(this.state);
+  }
+}
+
+QueryBox.contextTypes = {
+  router: React.PropTypes.func
+};
+
+export default QueryBox;


[03/50] [abbrv] lens git commit: LENS-757: Examples should continue to run in case submission failures

Posted by ra...@apache.org.
LENS-757: Examples should continue to run in case submission failures


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

Branch: refs/heads/current-release-line
Commit: fa8e5206ffda1d4cdc6db13feac195d4b0caf9d0
Parents: af31166
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Wed Aug 26 20:17:57 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Wed Aug 26 20:17:57 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/examples/SampleQueries.java | 52 +++++++++++---------
 1 file changed, 29 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/fa8e5206/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java
----------------------------------------------------------------------
diff --git a/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java b/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java
index 6b662e7..805a282 100644
--- a/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java
+++ b/lens-examples/src/main/java/org/apache/lens/examples/SampleQueries.java
@@ -26,6 +26,7 @@ import java.io.InputStreamReader;
 import javax.xml.bind.JAXBException;
 
 import org.apache.lens.api.query.*;
+import org.apache.lens.client.LensClient;
 import org.apache.lens.client.LensClientSingletonWrapper;
 import org.apache.lens.client.LensMetadataClient;
 import org.apache.lens.client.LensStatement;
@@ -83,9 +84,6 @@ public class SampleQueries {
         }
       }
       queries.queryAll();
-      if (queries.retCode != 0) {
-        System.exit(queries.retCode);
-      }
     } finally {
       if (queries != null) {
         queries.close();
@@ -93,6 +91,9 @@ public class SampleQueries {
       long end = System.currentTimeMillis();
       System.out.println("Total time for running examples(in millis) :" + (end-start));
     }
+    if (queries.retCode != 0) {
+      System.exit(queries.retCode);
+    }
   }
 
   /**
@@ -132,29 +133,34 @@ public class SampleQueries {
       }
       total++;
       System.out.println("Query:" + query);
-      QueryHandle handle = queryClient.executeQuery(query, true, null).getData();
-      System.out.println("Status:" + queryClient.getQuery().getStatus());
-      System.out.println("Total time in millis:"
-        + (queryClient.getQuery().getFinishTime() - queryClient.getQuery().getSubmissionTime()));
-      System.out.println("Driver run time in millis:"
-        + (queryClient.getQuery().getDriverFinishTime() - queryClient.getQuery().getDriverStartTime()));
-      if (queryClient.wasQuerySuccessful()) {
-        success++;
-        if (queryClient.getQuery().getStatus().isResultSetAvailable()) {
-          System.out.println("Result:");
-          QueryResult queryResult = queryClient.getResultSet();
-          if (queryResult instanceof InMemoryQueryResult) {
-            InMemoryQueryResult result = (InMemoryQueryResult) queryResult;
-            for (ResultRow row : result.getRows()) {
-              System.out.println(StringUtils.join(row.getValues(), "\t"));
+      try {
+        QueryHandle handle = queryClient.executeQuery(query, true, null).getData();
+        System.out.println("Status:" + queryClient.getQuery().getStatus());
+        System.out.println("Total time in millis:"
+          + (queryClient.getQuery().getFinishTime() - queryClient.getQuery().getSubmissionTime()));
+        System.out.println("Driver run time in millis:"
+          + (queryClient.getQuery().getDriverFinishTime() - queryClient.getQuery().getDriverStartTime()));
+        if (queryClient.wasQuerySuccessful()) {
+          success++;
+          if (queryClient.getQuery().getStatus().isResultSetAvailable()) {
+            System.out.println("Result:");
+            QueryResult queryResult = queryClient.getResultSet();
+            if (queryResult instanceof InMemoryQueryResult) {
+              InMemoryQueryResult result = (InMemoryQueryResult) queryResult;
+              for (ResultRow row : result.getRows()) {
+                System.out.println(StringUtils.join(row.getValues(), "\t"));
+              }
+            } else if (queryResult instanceof PersistentQueryResult) {
+              PersistentQueryResult persistentQueryResult = (PersistentQueryResult) queryResult;
+              System.out.println("Result stored at " + persistentQueryResult.getPersistedURI());
             }
-          } else if (queryResult instanceof PersistentQueryResult) {
-            PersistentQueryResult persistentQueryResult = (PersistentQueryResult) queryResult;
-            System.out.println("Result stored at " + persistentQueryResult.getPersistedURI());
+            queryClient.closeResultSet();
           }
-          queryClient.closeResultSet();
+        } else {
+          retCode = 1;
         }
-      } else {
+      } catch (Exception e) {
+        LensClient.getCliLooger().error("Exception for example query : \"{}\"", query, e);
         retCode = 1;
       }
       System.out.println("--------------------");


[33/50] [abbrv] lens git commit: LENS-777: Fix: Waiting query selector change from intersecting to union

Posted by ra...@apache.org.
LENS-777: Fix: Waiting query selector change from intersecting to union


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/7ad12ed7
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/7ad12ed7
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/7ad12ed7

Branch: refs/heads/current-release-line
Commit: 7ad12ed738abbf14d0b5bfe29dd45de209d32167
Parents: 66f164b
Author: Akshay Goyal <ak...@gmail.com>
Authored: Wed Sep 23 17:39:34 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Wed Sep 23 17:39:34 2015 +0530

----------------------------------------------------------------------
 .../server/query/QueryExecutionServiceImpl.java |   2 +-
 .../IntersectingWaitingQueriesSelector.java     | 107 -----------
 .../collect/UnioningWaitingQueriesSelector.java |  93 ++++++++++
 .../IntersectingWaitingQueriesSelectorTest.java | 185 -------------------
 .../UnioningWaitingQueriesSelectorTest.java     | 135 ++++++++++++++
 5 files changed, 229 insertions(+), 293 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/7ad12ed7/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 2ba54e0..3bc9a4a 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -1026,7 +1026,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies = getImplementations(
       WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY, hiveConf);
 
-    this.waitingQueriesSelector = new IntersectingWaitingQueriesSelector(selectionPolicies);
+    this.waitingQueriesSelector = new UnioningWaitingQueriesSelector(selectionPolicies);
 
     try {
       this.userQueryToCubeQueryRewriter = new UserQueryToCubeQueryRewriter(conf);

http://git-wip-us.apache.org/repos/asf/lens/blob/7ad12ed7/lens-server/src/main/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelector.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelector.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelector.java
deleted file mode 100644
index fee4120..0000000
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelector.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.lens.server.query.collect;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.lens.server.api.query.FinishedLensQuery;
-import org.apache.lens.server.api.query.QueryContext;
-import org.apache.lens.server.api.query.collect.EstimatedImmutableQueryCollection;
-import org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import lombok.NonNull;
-
-/**
- * Selects queries eligible by all {@link WaitingQueriesSelectionPolicy} to move them out of waiting state.
- *
- */
-public class IntersectingWaitingQueriesSelector implements WaitingQueriesSelector {
-
-  private final ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies;
-
-  public IntersectingWaitingQueriesSelector(
-      @NonNull final ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies) {
-    this.selectionPolicies = selectionPolicies;
-  }
-
-  /**
-   * Selects queries eligible by all {@link WaitingQueriesSelectionPolicy} to move them out of waiting state.
-   *
-   * @see WaitingQueriesSelector#selectQueries(FinishedLensQuery, EstimatedImmutableQueryCollection)
-   *
-   * @param finishedQuery
-   * @param waitingQueries
-   * @return
-   */
-  @Override
-  public Set<QueryContext> selectQueries(final FinishedLensQuery finishedQuery,
-      final EstimatedImmutableQueryCollection waitingQueries) {
-
-    Set<WaitingQueriesSelectionPolicy> allSelectionPolicies = prepareAllSelectionPolicies(finishedQuery);
-
-    List<Set<QueryContext>> candiateQueriesSets = getAllCandidateQueriesSets(finishedQuery, waitingQueries,
-        allSelectionPolicies);
-
-    return findCommonQueries(candiateQueriesSets);
-  }
-
-  @VisibleForTesting
-  Set<WaitingQueriesSelectionPolicy> prepareAllSelectionPolicies(final FinishedLensQuery finishedQuery) {
-
-    /* Get the selection policies of driver on which this query was run */
-    ImmutableSet<WaitingQueriesSelectionPolicy> driverSelectionPolicies = finishedQuery.getDriverSelectionPolicies();
-
-    return Sets.union(this.selectionPolicies, driverSelectionPolicies);
-  }
-
-  private List<Set<QueryContext>> getAllCandidateQueriesSets(
-      final FinishedLensQuery finishedQuery, final EstimatedImmutableQueryCollection waitingQueries,
-      final Set<WaitingQueriesSelectionPolicy> allSelectionPolicies) {
-
-    List<Set<QueryContext>> candidateQueriesSets = Lists.newLinkedList();
-
-    for (final WaitingQueriesSelectionPolicy selectionPolicy : allSelectionPolicies) {
-
-      Set<QueryContext> candiateQueries = selectionPolicy.selectQueries(finishedQuery, waitingQueries);
-      candidateQueriesSets.add(candiateQueries);
-    }
-    return candidateQueriesSets;
-  }
-
-  @VisibleForTesting
-  Set<QueryContext> findCommonQueries(final List<Set<QueryContext>> candiateQueriesSets) {
-
-    Set<QueryContext> commonQueries = Sets.newLinkedHashSet();
-
-    if (!candiateQueriesSets.isEmpty()) {
-      commonQueries = Iterables.get(candiateQueriesSets, 0);
-
-      for (Set<QueryContext> candidateEligibleQueries : candiateQueriesSets) {
-        commonQueries.retainAll(candidateEligibleQueries);
-      }
-    }
-    return commonQueries;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lens/blob/7ad12ed7/lens-server/src/main/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelector.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelector.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelector.java
new file mode 100644
index 0000000..8db059e
--- /dev/null
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelector.java
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.server.query.collect;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.lens.server.api.query.FinishedLensQuery;
+import org.apache.lens.server.api.query.QueryContext;
+import org.apache.lens.server.api.query.collect.EstimatedImmutableQueryCollection;
+import org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import lombok.NonNull;
+
+/**
+ * Selects queries eligible by all {@link WaitingQueriesSelectionPolicy} to move them out of waiting state.
+ *
+ */
+public class UnioningWaitingQueriesSelector implements WaitingQueriesSelector {
+
+  private final ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies;
+
+  public UnioningWaitingQueriesSelector(
+    @NonNull final ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies) {
+    this.selectionPolicies = selectionPolicies;
+  }
+
+  /**
+   * Selects queries eligible by all {@link WaitingQueriesSelectionPolicy} to move them out of waiting state.
+   *
+   * @see WaitingQueriesSelector#selectQueries(FinishedLensQuery, EstimatedImmutableQueryCollection)
+   *
+   * @param finishedQuery
+   * @param waitingQueries
+   * @return
+   */
+  @Override
+  public Set<QueryContext> selectQueries(final FinishedLensQuery finishedQuery,
+      final EstimatedImmutableQueryCollection waitingQueries) {
+
+    Set<WaitingQueriesSelectionPolicy> allSelectionPolicies = prepareAllSelectionPolicies(finishedQuery);
+
+    List<Set<QueryContext>> candiateQueriesSets = getAllCandidateQueriesSets(finishedQuery, waitingQueries,
+        allSelectionPolicies);
+
+    return Sets.newHashSet(Iterables.concat(candiateQueriesSets));
+  }
+
+  @VisibleForTesting
+  Set<WaitingQueriesSelectionPolicy> prepareAllSelectionPolicies(final FinishedLensQuery finishedQuery) {
+
+    /* Get the selection policies of driver on which this query was run */
+    ImmutableSet<WaitingQueriesSelectionPolicy> driverSelectionPolicies = finishedQuery.getDriverSelectionPolicies();
+
+    return Sets.union(this.selectionPolicies, driverSelectionPolicies);
+  }
+
+  private List<Set<QueryContext>> getAllCandidateQueriesSets(
+      final FinishedLensQuery finishedQuery, final EstimatedImmutableQueryCollection waitingQueries,
+      final Set<WaitingQueriesSelectionPolicy> allSelectionPolicies) {
+
+    List<Set<QueryContext>> candidateQueriesSets = Lists.newLinkedList();
+
+    for (final WaitingQueriesSelectionPolicy selectionPolicy : allSelectionPolicies) {
+
+      Set<QueryContext> candiateQueries = selectionPolicy.selectQueries(finishedQuery, waitingQueries);
+      candidateQueriesSets.add(candiateQueries);
+    }
+    return candidateQueriesSets;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/7ad12ed7/lens-server/src/test/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelectorTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelectorTest.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelectorTest.java
deleted file mode 100644
index 62e371d..0000000
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/IntersectingWaitingQueriesSelectorTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.lens.server.query.collect;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.lens.server.api.query.FinishedLensQuery;
-import org.apache.lens.server.api.query.QueryContext;
-import org.apache.lens.server.api.query.collect.EstimatedImmutableQueryCollection;
-import org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy;
-
-import org.testng.annotations.Test;
-import org.testng.collections.Sets;
-
-import com.beust.jcommander.internal.Lists;
-import com.google.common.collect.ImmutableSet;
-
-public class IntersectingWaitingQueriesSelectorTest {
-
-  @Test
-  public void testFindCommonQueriesWhenInputIsEmptyListOfSets() {
-
-    List<Set<QueryContext>> candidateQueriesSets = Lists.newArrayList();
-    Set<QueryContext> expectedEligibleQueries = Sets.newHashSet();
-
-    testFindCommonQueries(candidateQueriesSets, expectedEligibleQueries);
-  }
-
-  @Test
-  public void testFindCommonQueriesWhenNoCommonQueryIsPresent() {
-
-    QueryContext eligibleQuery1 = mock(QueryContext.class);
-    QueryContext eligibleQuery2 = mock(QueryContext.class);
-
-    Set<QueryContext> eligibleQueriesSetA = Sets.newHashSet(Arrays.asList(eligibleQuery1));
-    Set<QueryContext> eligibleQueriesSetB = Sets.newHashSet(Arrays.asList(eligibleQuery2));
-
-    List<Set<QueryContext>> candidateQueriesSets = Arrays.asList(eligibleQueriesSetA, eligibleQueriesSetB);
-    Set<QueryContext> expectedEligibleQueries = Sets.newHashSet();
-
-    testFindCommonQueries(candidateQueriesSets, expectedEligibleQueries);
-  }
-
-  @Test
-  public void testFindCommonQueriesWhenACommonQueryIsPresent() {
-
-    QueryContext eligibleQuery1 = mock(QueryContext.class);
-    QueryContext eligibleQuery2 = mock(QueryContext.class);
-    QueryContext eligibleQuery3 = mock(QueryContext.class);
-
-    Set<QueryContext> eligibleQueriesSetA = Sets.newHashSet(Arrays.asList(eligibleQuery1, eligibleQuery2));
-    Set<QueryContext> eligibleQueriesSetB = Sets.newHashSet(Arrays.asList(eligibleQuery1, eligibleQuery3));
-
-    List<Set<QueryContext>> candidateQueriesSets = Arrays.asList(eligibleQueriesSetA, eligibleQueriesSetB);
-    Set<QueryContext> expectedEligibleQueries = Sets.newHashSet(Arrays.asList(eligibleQuery1));
-
-    testFindCommonQueries(candidateQueriesSets, expectedEligibleQueries);
-  }
-
-  private void testFindCommonQueries(final List<Set<QueryContext>> queriesSets,
-      final Set<QueryContext> expectedEligibleQueries) {
-
-    IntersectingWaitingQueriesSelector selector = new IntersectingWaitingQueriesSelector(mock(ImmutableSet.class));
-
-    Set<QueryContext> actualCommonQueries = selector.findCommonQueries(queriesSets);
-    assertEquals(actualCommonQueries, expectedEligibleQueries);
-  }
-
-  @Test
-  public void testPrepareAllSelectionPolicies() {
-
-    WaitingQueriesSelectionPolicy p1 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy p2 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy dp1 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy dp2 = mock(WaitingQueriesSelectionPolicy.class);
-
-    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
-    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.of(dp1, dp2));
-
-    IntersectingWaitingQueriesSelector selector = new IntersectingWaitingQueriesSelector(ImmutableSet.of(p1, p2));
-    assertEquals(selector.prepareAllSelectionPolicies(mockFinishedQuery), ImmutableSet.of(p1, p2, dp1, dp2));
-  }
-
-  @Test
-  public void testPrepareAllSelectionPoliciesWithNoDriverSelectionPolicy() {
-
-    WaitingQueriesSelectionPolicy p1 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy p2 = mock(WaitingQueriesSelectionPolicy.class);
-
-    final ImmutableSet<WaitingQueriesSelectionPolicy> emptySet = ImmutableSet.copyOf(
-        Sets.<WaitingQueriesSelectionPolicy>newHashSet());
-
-    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
-    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(emptySet);
-
-    IntersectingWaitingQueriesSelector selector = new IntersectingWaitingQueriesSelector(ImmutableSet.of(p1, p2));
-
-    assertEquals(selector.prepareAllSelectionPolicies(mockFinishedQuery), ImmutableSet.of(p1, p2));
-  }
-
-  @Test
-  public void testSelectQueriesCommonBetweenAllSelectionPolicies(){
-
-    QueryContext q1 = mock(QueryContext.class);
-    QueryContext q2 = mock(QueryContext.class);
-    QueryContext q3 = mock(QueryContext.class);
-
-    /* eligibleQueriesSet1, eligibleQueriesSet2, eligibleQueriesSet3 have q1 in common */
-    Set<QueryContext> eligibleQueriesSet1 = Sets.newHashSet(Arrays.asList(q1, q2));
-    Set<QueryContext> eligibleQueriesSet2 = Sets.newHashSet(Arrays.asList(q1, q3));
-    Set<QueryContext> eligibleQueriesSet3 = Sets.newHashSet(Arrays.asList(q1, q2));
-
-    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
-    EstimatedImmutableQueryCollection mockWaitingQueries = mock(EstimatedImmutableQueryCollection.class);
-    WaitingQueriesSelectionPolicy policy1 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy policy2 = mock(WaitingQueriesSelectionPolicy.class);
-    WaitingQueriesSelectionPolicy driverSelectionPolicy = mock(WaitingQueriesSelectionPolicy.class);
-
-    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.of(driverSelectionPolicy));
-
-    /* selection policy1 will return eligibleQueriesSet1 */
-    when(policy1.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet1);
-
-    /* selection policy2 will return eligibleQueriesSet2 */
-    when(policy2.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet2);
-
-    /* driver selection policy will return eligibleQueriesSet3 */
-    when(driverSelectionPolicy.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet3);
-
-    WaitingQueriesSelector selector = new IntersectingWaitingQueriesSelector(ImmutableSet.of(policy1, policy2));
-
-    /* selector should return only eligibleQuery1, as this is the only common eligible waiting query returned
-    * by both selection policies */
-    Set<QueryContext> actualEligibleQueries = selector.selectQueries(mockFinishedQuery, mockWaitingQueries);
-    Set<QueryContext> expectedEligibleQueries = Sets.newHashSet(Arrays.asList(q1));
-
-    assertEquals(actualEligibleQueries, expectedEligibleQueries);
-  }
-
-  @Test(expectedExceptions = NullPointerException.class)
-  public void testSelectorMustNotAcceptNullAsSelectionPolicies() {
-    new IntersectingWaitingQueriesSelector(null);
-  }
-
-  @Test
-  public void testSelectQueriesWithNoSelectionPolicies(){
-
-    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
-    EstimatedImmutableQueryCollection mockWaitingQueries = mock(EstimatedImmutableQueryCollection.class);
-    Set<WaitingQueriesSelectionPolicy> emptySetOfPolicies = Sets.newHashSet();
-
-    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.copyOf(emptySetOfPolicies));
-
-    WaitingQueriesSelector selector = new IntersectingWaitingQueriesSelector(ImmutableSet.copyOf(emptySetOfPolicies));
-
-    /* selector should return an empty set as no selection policy is available */
-    Set<QueryContext> actualEligibleQueries = selector.selectQueries(mockFinishedQuery, mockWaitingQueries);
-
-    assertTrue(actualEligibleQueries.isEmpty());
-  }
-}

http://git-wip-us.apache.org/repos/asf/lens/blob/7ad12ed7/lens-server/src/test/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelectorTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelectorTest.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelectorTest.java
new file mode 100644
index 0000000..98801de
--- /dev/null
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/UnioningWaitingQueriesSelectorTest.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.lens.server.query.collect;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.lens.server.api.query.FinishedLensQuery;
+import org.apache.lens.server.api.query.QueryContext;
+import org.apache.lens.server.api.query.collect.EstimatedImmutableQueryCollection;
+import org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy;
+
+import org.testng.annotations.Test;
+import org.testng.collections.Sets;
+
+import com.google.common.collect.ImmutableSet;
+
+public class UnioningWaitingQueriesSelectorTest {
+
+  @Test
+  public void testPrepareAllSelectionPolicies() {
+
+    WaitingQueriesSelectionPolicy p1 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy p2 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy dp1 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy dp2 = mock(WaitingQueriesSelectionPolicy.class);
+
+    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
+    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.of(dp1, dp2));
+
+    UnioningWaitingQueriesSelector selector = new UnioningWaitingQueriesSelector(ImmutableSet.of(p1, p2));
+    assertEquals(selector.prepareAllSelectionPolicies(mockFinishedQuery), ImmutableSet.of(p1, p2, dp1, dp2));
+  }
+
+  @Test
+  public void testPrepareAllSelectionPoliciesWithNoDriverSelectionPolicy() {
+
+    WaitingQueriesSelectionPolicy p1 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy p2 = mock(WaitingQueriesSelectionPolicy.class);
+
+    final ImmutableSet<WaitingQueriesSelectionPolicy> emptySet = ImmutableSet.copyOf(
+      Sets.<WaitingQueriesSelectionPolicy>newHashSet());
+
+    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
+    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(emptySet);
+
+    UnioningWaitingQueriesSelector selector = new UnioningWaitingQueriesSelector(ImmutableSet.of(p1, p2));
+
+    assertEquals(selector.prepareAllSelectionPolicies(mockFinishedQuery), ImmutableSet.of(p1, p2));
+  }
+
+  @Test
+  public void testSelectQueriesWithAllSelectionPolicies(){
+
+    QueryContext q1 = mock(QueryContext.class);
+    QueryContext q2 = mock(QueryContext.class);
+    QueryContext q3 = mock(QueryContext.class);
+
+    /* eligibleQueriesSet1, eligibleQueriesSet2, eligibleQueriesSet3 have q1 in common */
+    Set<QueryContext> eligibleQueriesSet1 = Sets.newHashSet(Arrays.asList(q1, q2));
+    Set<QueryContext> eligibleQueriesSet2 = Sets.newHashSet(Arrays.asList(q1, q3));
+    Set<QueryContext> eligibleQueriesSet3 = Sets.newHashSet(Arrays.asList(q1, q2));
+
+    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
+    EstimatedImmutableQueryCollection mockWaitingQueries = mock(EstimatedImmutableQueryCollection.class);
+    WaitingQueriesSelectionPolicy policy1 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy policy2 = mock(WaitingQueriesSelectionPolicy.class);
+    WaitingQueriesSelectionPolicy driverSelectionPolicy = mock(WaitingQueriesSelectionPolicy.class);
+
+    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.of(driverSelectionPolicy));
+
+    /* selection policy1 will return eligibleQueriesSet1 */
+    when(policy1.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet1);
+
+    /* selection policy2 will return eligibleQueriesSet2 */
+    when(policy2.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet2);
+
+    /* driver selection policy will return eligibleQueriesSet3 */
+    when(driverSelectionPolicy.selectQueries(mockFinishedQuery, mockWaitingQueries)).thenReturn(eligibleQueriesSet3);
+
+    WaitingQueriesSelector selector = new UnioningWaitingQueriesSelector(ImmutableSet.of(policy1, policy2));
+
+    /* selector should return only eligibleQuery1, as this is the only common eligible waiting query returned
+    * by both selection policies */
+    Set<QueryContext> actualEligibleQueries = selector.selectQueries(mockFinishedQuery, mockWaitingQueries);
+    Set<QueryContext> expectedEligibleQueries = Sets.newHashSet(Arrays.asList(q1, q2, q3));
+
+    assertEquals(actualEligibleQueries, expectedEligibleQueries);
+  }
+
+  @Test(expectedExceptions = NullPointerException.class)
+  public void testSelectorMustNotAcceptNullAsSelectionPolicies() {
+    new UnioningWaitingQueriesSelector(null);
+  }
+
+  @Test
+  public void testSelectQueriesWithNoSelectionPolicies(){
+
+    FinishedLensQuery mockFinishedQuery = mock(FinishedLensQuery.class);
+    EstimatedImmutableQueryCollection mockWaitingQueries = mock(EstimatedImmutableQueryCollection.class);
+    Set<WaitingQueriesSelectionPolicy> emptySetOfPolicies = Sets.newHashSet();
+
+    when(mockFinishedQuery.getDriverSelectionPolicies()).thenReturn(ImmutableSet.copyOf(emptySetOfPolicies));
+
+    WaitingQueriesSelector selector = new UnioningWaitingQueriesSelector(ImmutableSet.copyOf(emptySetOfPolicies));
+
+    /* selector should return an empty set as no selection policy is available */
+    Set<QueryContext> actualEligibleQueries = selector.selectQueries(mockFinishedQuery, mockWaitingQueries);
+
+    assertTrue(actualEligibleQueries.isEmpty());
+  }
+
+}


[18/50] [abbrv] lens git commit: LENS-753: Queue number for queries in submitted queue

Posted by ra...@apache.org.
LENS-753: Queue number for queries in submitted queue


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/4addd7b6
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/4addd7b6
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/4addd7b6

Branch: refs/heads/current-release-line
Commit: 4addd7b62ed1db8fe1af498a6baf55ee35ad692a
Parents: 3563aac
Author: Akshay Goyal <ak...@gmail.com>
Authored: Tue Sep 15 16:29:32 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Tue Sep 15 16:29:32 2015 +0530

----------------------------------------------------------------------
 .../org/apache/lens/api/query/QueryStatus.java  | 38 +++++++++++++++----
 .../lens/cli/commands/LensQueryCommands.java    | 18 +--------
 .../server/api/driver/DriverQueryStatus.java    |  7 ++--
 .../server/api/query/FinishedLensQuery.java     |  2 +-
 .../lens/server/api/query/QueryContext.java     |  2 +-
 .../query/collect/ImmutableQueryCollection.java |  6 +++
 .../server/query/QueryExecutionServiceImpl.java | 26 ++++++++-----
 .../DefaultEstimatedQueryCollection.java        |  5 +++
 .../query/collect/DefaultQueryCollection.java   | 36 ++++++++++++++++--
 .../ThreadSafeEstimatedQueryCollection.java     |  5 +++
 .../collect/ThreadSafeQueryCollection.java      |  5 +++
 .../collect/DefaultQueryCollectionTest.java     | 34 ++++++++++++++++-
 .../server/query/collect/QueryCollectUtil.java  | 39 +++++++++++++++++++-
 13 files changed, 178 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
index 9614caa..3c8531f 100644
--- a/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
+++ b/lens-api/src/main/java/org/apache/lens/api/query/QueryStatus.java
@@ -39,6 +39,8 @@ import lombok.*;
  *
  * @param progress
  *          the progress
+ * @param queueNumber
+ *          the queue number
  * @param status
  *          the status
  * @param statusMessage
@@ -121,6 +123,13 @@ public class QueryStatus implements Serializable {
   private double progress;
 
   /**
+   * Queue number of a query when it is in waiting state.
+   */
+  @Getter
+  @Setter
+  private Integer queueNumber;
+
+  /**
    * The status.
    */
   @XmlElement
@@ -165,20 +174,33 @@ public class QueryStatus implements Serializable {
    */
   @Override
   public String toString() {
-    StringBuilder str = new StringBuilder(status.toString()).append(':').append(statusMessage);
-    if (status.equals(Status.RUNNING)) {
-      str.append(" - Progress:").append(progress).append(":").append(progressMessage);
+
+    StringBuilder str = new StringBuilder(" Status : ").append(status.toString()).append("\n");
+    if (statusMessage != null) {
+      str.append(" Message : ").append(statusMessage).append("\n");
+    }
+
+    str.append(" Progress : ").append(progress).append("\n");
+    if (progressMessage != null) {
+      str.append(" Progress Message : ").append(progressMessage).append("\n");
     }
+
+    if (queueNumber != null) {
+      str.append(" Position in queue : ").append(queueNumber).append("\n");
+    }
+
+    if (errorMessage != null) {
+      str.append(" Error : ").append(errorMessage).append("\n");
+    }
+
     if (status.equals(Status.SUCCESSFUL)) {
       if (isResultSetAvailable) {
-        str.append(" - Result Available");
+        str.append(" Result Available");
       } else {
-        str.append(" - Result Not Available");
+        str.append(" Result Not Available");
       }
     }
-    if (status.equals(Status.FAILED)) {
-      str.append(" - Cause:").append(errorMessage);
-    }
+
     return str.toString();
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
index 44c0c62..006eaed 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java
@@ -156,26 +156,10 @@ public class LensQueryCommands extends BaseLensCommand {
   public String getStatus(
     @CliOption(key = {"", "query_handle"}, mandatory = true, help = "<query_handle>") String qh) {
     QueryStatus status = getClient().getQueryStatus(new QueryHandle(UUID.fromString(qh)));
-    StringBuilder sb = new StringBuilder();
     if (status == null) {
       return "Unable to find status for " + qh;
     }
-    sb.append("Status : ").append(status.getStatus()).append("\n");
-    if (status.getStatusMessage() != null) {
-      sb.append("Message : ").append(status.getStatusMessage()).append("\n");
-    }
-    if (status.getProgress() != 0) {
-      sb.append("Progress : ").append(status.getProgress()).append("\n");
-      if (status.getProgressMessage() != null) {
-        sb.append("Progress Message : ").append(status.getProgressMessage()).append("\n");
-      }
-    }
-
-    if (status.getErrorMessage() != null) {
-      sb.append("Error : ").append(status.getErrorMessage()).append("\n");
-    }
-
-    return sb.toString();
+    return status.toString();
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
index f78b7c3..79d8bf1 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/driver/DriverQueryStatus.java
@@ -167,7 +167,8 @@ public class DriverQueryStatus implements Serializable {
       break;
     }
 
-    return new QueryStatus(progress, qstate, statusMessage, isResultSetAvailable, progressMessage, errorMessage, null);
+    return new QueryStatus(progress, null, qstate, statusMessage, isResultSetAvailable, progressMessage,
+            errorMessage, null);
   }
 
   /**
@@ -178,8 +179,8 @@ public class DriverQueryStatus implements Serializable {
    * @return the query status
    */
   public static QueryStatus createQueryStatus(QueryStatus.Status state, DriverQueryStatus dstatus) {
-    return new QueryStatus(dstatus.progress, state, dstatus.statusMessage, dstatus.isResultSetAvailable,
-      dstatus.progressMessage, dstatus.errorMessage, null);
+    return new QueryStatus(dstatus.progress, null, state, dstatus.statusMessage,
+            dstatus.isResultSetAvailable, dstatus.progressMessage, dstatus.errorMessage, null);
   }
 
   /*

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
index 6cecf7e..d8c04db 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
@@ -204,7 +204,7 @@ public class FinishedLensQuery {
     qctx.setQueryHandle(QueryHandle.fromString(handle));
     qctx.setLaunchTime(this.startTime);
     qctx.setEndTime(getEndTime());
-    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, QueryStatus.Status.valueOf(getStatus()),
+    qctx.setStatusSkippingTransitionTest(new QueryStatus(0.0, null, QueryStatus.Status.valueOf(getStatus()),
         getErrorMessage() == null ? "" : getErrorMessage(), getResult() != null, null, null, null));
     qctx.getDriverStatus().setDriverStartTime(getDriverStartTime());
     qctx.getDriverStatus().setDriverFinishTime(getDriverEndTime());

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
index beaa72f..12de0a5 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/QueryContext.java
@@ -217,7 +217,7 @@ public class QueryContext extends AbstractQueryContext {
     super(userQuery, user, qconf, conf, drivers, mergeDriverConf);
     this.submissionTime = submissionTime;
     this.queryHandle = new QueryHandle(UUID.randomUUID());
-    this.status = new QueryStatus(0.0f, Status.NEW, "Query just got created", false, null, null, null);
+    this.status = new QueryStatus(0.0f, null, Status.NEW, "Query just got created", false, null, null, null);
     this.priority = Priority.NORMAL;
     this.lensConf = qconf;
     this.conf = conf;

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
index 344ff10..0dcf367 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/collect/ImmutableQueryCollection.java
@@ -50,4 +50,10 @@ public interface ImmutableQueryCollection {
    * @return Count of existing queries
    */
   int getQueriesCount();
+
+  /**
+   *
+   * @return Index of a query within collection
+   */
+  Integer getQueryIndex(final QueryContext query);
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 23cc748..9e27dd4 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -615,8 +615,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
       checkEstimatedQueriesState(query);
       QueryStatus oldStatus = query.getStatus();
-      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), QueryStatus.Status.LAUNCHED,
-          "Query is launched on driver", false, null, null, null);
+      QueryStatus newStatus = new QueryStatus(query.getStatus().getProgress(), null,
+        QueryStatus.Status.LAUNCHED, "Query is launched on driver", false, null, null, null);
       query.validateTransition(newStatus);
 
       // Check if we need to pass session's effective resources to selected driver
@@ -717,7 +717,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
     throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, FAILED, statusMsg, false, null, reason, lensErrorTO));
+    ctx.setStatus(new QueryStatus(0.0f, null, FAILED, statusMsg, false, null, reason, lensErrorTO));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -731,7 +731,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
    */
   private void setCancelledStatus(QueryContext ctx, String statusMsg) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0f, CANCELED, statusMsg, false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0f, null, CANCELED, statusMsg, false, null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
   }
@@ -765,7 +765,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
   void setSuccessState(QueryContext ctx) throws LensException {
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(1.0f, SUCCESSFUL, "Query is successful!", ctx
+    ctx.setStatus(new QueryStatus(1.0f, null, SUCCESSFUL, "Query is successful!", ctx
       .isResultAvailableInDriver(), null, null, null));
     updateFinishedQuery(ctx, before);
     fireStatusChangeEvent(ctx, ctx.getStatus(), before);
@@ -807,6 +807,14 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             fireStatusChangeEvent(ctx, ctx.getStatus(), before);
           }
         }
+        if (ctx.queued()) {
+          Integer queryIndex = waitingQueries.getQueryIndex(ctx);
+          // Query index could be null when the query status is queued but
+          // query is present in priorityblocking queue for processing
+          if (queryIndex != null) {
+            ctx.getStatus().setQueueNumber(queryIndex);
+          }
+        }
       }
     }
   }
@@ -946,7 +954,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
             resultSets.remove(finished.getCtx().getQueryHandle());
           }
           fireStatusChangeEvent(finished.getCtx(),
-            new QueryStatus(1f, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
+            new QueryStatus(1f, null, CLOSED, "Query purged", false, null, null, null), finished.getCtx().getStatus());
           log.info("Query purged: {}", finished.getCtx().getQueryHandle());
 
         } catch (LensException e) {
@@ -1006,8 +1014,8 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
 
     this.launchedQueries
       = new ThreadSafeEstimatedQueryCollection(new DefaultEstimatedQueryCollection(new DefaultQueryCollection()));
-    this.waitingQueries
-      = new ThreadSafeEstimatedQueryCollection(new DefaultEstimatedQueryCollection(new DefaultQueryCollection()));
+    this.waitingQueries = new ThreadSafeEstimatedQueryCollection(new DefaultEstimatedQueryCollection(
+      new DefaultQueryCollection(new TreeSet<QueryContext>(new QueryContextPriorityComparator()))));
 
     ImmutableSet<QueryLaunchingConstraint> queryConstraints = getImplementations(
         QUERY_LAUNCHING_CONSTRAINT_FACTORIES_KEY, hiveConf);
@@ -1696,7 +1704,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   private QueryHandle submitQuery(final QueryContext ctx) throws LensException {
 
     QueryStatus before = ctx.getStatus();
-    ctx.setStatus(new QueryStatus(0.0, QUEUED, "Query is queued", false, null, null, null));
+    ctx.setStatus(new QueryStatus(0.0, null, QUEUED, "Query is queued", false, null, null, null));
     queuedQueries.add(ctx);
     log.debug("Added to Queued Queries:{}", ctx.getQueryHandleString());
     allQueries.put(ctx.getQueryHandle(), ctx);

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
index e3505bb..908b86f 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultEstimatedQueryCollection.java
@@ -138,6 +138,11 @@ public class DefaultEstimatedQueryCollection implements EstimatedQueryCollection
     return this.queries.getQueriesCount();
   }
 
+  @Override
+  public Integer getQueryIndex(QueryContext query) {
+    return this.queries.getQueryIndex(query);
+  }
+
   @VisibleForTesting
   void checkState(final QueryContext query) {
     Preconditions.checkState(query.getSelectedDriver() != null);

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
index f9e7701..844237a 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/DefaultQueryCollection.java
@@ -26,7 +26,6 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.map.MultiValueMap;
 
 import com.google.common.collect.Sets;
-import lombok.NoArgsConstructor;
 import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
 
@@ -36,17 +35,28 @@ import lombok.extern.slf4j.Slf4j;
  *
  * @see QueryCollection
  */
-@NoArgsConstructor
 @Slf4j
 public class DefaultQueryCollection implements QueryCollection {
 
-  private final Set<QueryContext> queries = Sets.newLinkedHashSet();
+  private final Set<QueryContext> queries;
   private final MultiValueMap queriesByUser = MultiValueMap.decorate(new HashMap(), LinkedHashSet.class);
 
+  public DefaultQueryCollection() {
+    this.queries = Sets.newLinkedHashSet();
+  }
+
   public DefaultQueryCollection(@NonNull final Set<QueryContext> queries) {
+    this();
     addAll(queries);
   }
 
+  public DefaultQueryCollection(final TreeSet<QueryContext> treeSet) {
+    this.queries = treeSet;
+    for (QueryContext query : treeSet) {
+      queriesByUser.put(query.getSubmittedUser(), query);
+    }
+  }
+
   @Override
   public boolean add(final QueryContext query) {
 
@@ -96,6 +106,26 @@ public class DefaultQueryCollection implements QueryCollection {
     return queries.size();
   }
 
+
+  /**
+   *  Since the collection is a linkedHashSet, the order of queries is always maintained.
+   * @param query
+   * @return
+   */
+  @Override
+  public Integer getQueryIndex(QueryContext query) {
+    Iterator iterator = queries.iterator();
+    int index = 1;
+    while (iterator.hasNext()) {
+      QueryContext queuedQuery = (QueryContext) iterator.next();
+      if (queuedQuery.getQueryHandle().equals(query.getQueryHandle())) {
+        return index;
+      }
+      index += 1;
+    }
+    return null;
+  }
+
   private Collection<QueryContext> getQueriesCollectionForUser(final String user) {
 
     final Collection<QueryContext> userQueries = queriesByUser.getCollection(user);

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
index cdbd2ad..5d24379 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeEstimatedQueryCollection.java
@@ -70,6 +70,11 @@ public class ThreadSafeEstimatedQueryCollection implements EstimatedQueryCollect
   }
 
   @Override
+  public synchronized Integer getQueryIndex(QueryContext query) {
+    return this.estimatedQueries.getQueryIndex(query);
+  }
+
+  @Override
   public synchronized boolean add(QueryContext query) {
     return this.estimatedQueries.add(query);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
index 7b43a38..a49c7de 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/collect/ThreadSafeQueryCollection.java
@@ -72,4 +72,9 @@ public class ThreadSafeQueryCollection implements QueryCollection {
   public synchronized int getQueriesCount() {
     return this.queries.getQueriesCount();
   }
+
+  @Override
+  public synchronized Integer getQueryIndex(QueryContext query) {
+    return this.queries.getQueryIndex(query);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
index 7a81e83..d4b6bdf 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/DefaultQueryCollectionTest.java
@@ -29,17 +29,25 @@ import java.util.Set;
 
 import org.apache.lens.server.api.query.QueryContext;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 public class DefaultQueryCollectionTest {
 
   private static final String MOCK_USER = "MockUserEmail";
+  private static final String MOCK_HANDLE = "0-0-0-0-";
+
+  @DataProvider
+  public Object[][] dpQueryCosts() {
+    return new Object[][]{{new double[]{20.0, 50.0, 10.0, 80.0, 40.0, }, }, };
+
+  }
 
   /* Note: Since verification of addition/removal required calling get methods,
   hence methods getQueriesCount and getQueries(user) are indirectly getting tested in these tests */
 
   @Test
-  public void testAddMethodAddsQueriesToAllViews(){
+  public void testAddMethodAddsQueriesToAllViews() {
 
     /* Initialization */
     final int noOfQueriesUsedInTest = 2;
@@ -75,6 +83,30 @@ public class DefaultQueryCollectionTest {
     assertEquals(queries.getQueries(MOCK_USER).size(), 0);
   }
 
+  @Test(dataProvider = "dpQueryCosts")
+  public void testRemoveMethodMustChangeQueryIndices(final double[] queryCosts) {
+
+    /* Initialization */
+    int numberOfQueries = queryCosts.length;
+    QueryCollection collection = createQueriesTreeSetWithQueryHandleAndCostStubbing(queryCosts, MOCK_HANDLE);
+
+    QueryContext completedQuery = getMockedQueryFromQueries(collection.getQueries(), MOCK_HANDLE, 1);
+    QueryContext queuedQuery = getMockedQueryFromQueries(collection.getQueries(), MOCK_HANDLE, 5);
+
+     /* Verification 1: Verifies that all queries were added into the collection*/
+    assertEquals(collection.getQueriesCount(), numberOfQueries);
+
+    /* Execution */
+    collection.remove(completedQuery);
+
+     /* Verification 2: Verifies that queries were removed from the collection */
+    assertEquals(collection.getQueriesCount(), numberOfQueries - 1);
+
+    /* Verification 3: Verifies that query index is decreased after removal of queries which were present before
+     them in the queries list */
+    assertEquals(collection.getQueryIndex(queuedQuery).intValue(), 2);
+  }
+
   @Test
   public void testGetQueriesMustReturnCopyOfUnderlyingCollection() {
 

http://git-wip-us.apache.org/repos/asf/lens/blob/4addd7b6/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
index 51fcf00..7789a4c 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/collect/QueryCollectUtil.java
@@ -22,14 +22,19 @@ package org.apache.lens.server.query.collect;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isSynchronized;
 
+import org.apache.lens.api.query.QueryHandle;
+import org.apache.lens.server.api.query.QueryContext;
+import org.apache.lens.server.api.query.cost.FactPartitionBasedQueryCost;
+import org.apache.lens.server.query.QueryContextPriorityComparator;
+
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertTrue;
 
 import java.lang.reflect.Method;
+import java.util.Iterator;
 import java.util.Set;
-
-import org.apache.lens.server.api.query.QueryContext;
+import java.util.TreeSet;
 
 import com.google.common.collect.Sets;
 
@@ -77,6 +82,36 @@ public class QueryCollectUtil {
     return new DefaultQueryCollection(mockQueries);
   }
 
+  public static QueryCollection createQueriesTreeSetWithQueryHandleAndCostStubbing(final double[] queryCosts,
+                                                                                   final String handlePrefix) {
+
+    TreeSet<QueryContext> mockQueries = new TreeSet<>(new QueryContextPriorityComparator());
+
+    for (int index = 1; index <= queryCosts.length; ++index) {
+      mockQueries.add(createQueryInstanceWithQueryHandleAndCostStubbing(handlePrefix, index, queryCosts[index - 1]));
+    }
+    return new DefaultQueryCollection(mockQueries);
+  }
+
+  public static QueryContext createQueryInstanceWithQueryHandleAndCostStubbing(String handlePrefix, int index,
+                                                                               double queryCost) {
+    QueryContext mockQuery = mock(QueryContext.class);
+    when(mockQuery.getQueryHandle()).thenReturn(QueryHandle.fromString(handlePrefix + index));
+    when(mockQuery.getSelectedDriverQueryCost()).thenReturn(new FactPartitionBasedQueryCost(queryCost));
+    return mockQuery;
+  }
+
+  public static QueryContext getMockedQueryFromQueries(Set<QueryContext> queries, String mockHandle, int index) {
+    Iterator iterator = queries.iterator();
+    while (iterator.hasNext()) {
+      QueryContext queuedQuery = (QueryContext) iterator.next();
+      if (queuedQuery.getQueryHandle().equals(QueryHandle.fromString(mockHandle + index))) {
+        return queuedQuery;
+      }
+    }
+    return null;
+  }
+
   public static QueryCollection stubMockQueryAndCreateQueriesInstance(final QueryContext mockQuery,
     final String mockUser) {
 


[37/50] [abbrv] lens git commit: LENS-224: FinishedLensQuery is not storing selectedDriver

Posted by ra...@apache.org.
LENS-224: FinishedLensQuery is not storing selectedDriver


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

Branch: refs/heads/current-release-line
Commit: e5b793c83f2a627d049fac7de2ceee7a730574de
Parents: 5bae273
Author: Deepak Barr <de...@gmail.com>
Authored: Mon Sep 28 19:03:15 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Mon Sep 28 19:03:15 2015 +0530

----------------------------------------------------------------------
 .../server/api/query/FinishedLensQuery.java     | 34 ++++++++++++++++++--
 .../apache/lens/server/query/LensServerDAO.java | 10 +++---
 2 files changed, 37 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/e5b793c8/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
index 7a06c44..8308198 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/query/FinishedLensQuery.java
@@ -19,6 +19,7 @@
 package org.apache.lens.server.api.query;
 
 import java.util.Collection;
+import java.util.Iterator;
 
 import org.apache.lens.api.LensConf;
 import org.apache.lens.api.query.QueryHandle;
@@ -164,6 +165,13 @@ public class FinishedLensQuery {
   @Setter
   private String queryName;
 
+  /**
+   * The selected driver class name.
+   */
+  @Getter
+  @Setter
+  private String driverClass;
+
   @Getter
   private LensDriver selectedDriver;
 
@@ -195,11 +203,21 @@ public class FinishedLensQuery {
       this.queryName = ctx.getQueryName().toLowerCase();
     }
     this.selectedDriver = ctx.getSelectedDriver();
+    if (null != ctx.getSelectedDriver()) {
+      this.driverClass = ctx.getSelectedDriver().getClass().getName();
+    }
   }
 
   public QueryContext toQueryContext(Configuration conf, Collection<LensDriver> drivers) {
-    QueryContext qctx = new QueryContext(userQuery, submitter, new LensConf(), conf, drivers, null, submissionTime,
-      false);
+
+    if (null == selectedDriver && null != driverClass) {
+      selectedDriver = getDriverFromClassName(drivers);
+    }
+
+    QueryContext qctx =
+      new QueryContext(userQuery, submitter, new LensConf(), conf, drivers, selectedDriver, submissionTime,
+        false);
+
     qctx.setQueryHandle(QueryHandle.fromString(handle));
     qctx.setLaunchTime(this.startTime);
     qctx.setEndTime(getEndTime());
@@ -212,6 +230,18 @@ public class FinishedLensQuery {
     return qctx;
   }
 
+  private LensDriver getDriverFromClassName(Collection<LensDriver> drivers) {
+    Iterator<LensDriver> iterator = drivers.iterator();
+    while (iterator.hasNext()) {
+      LensDriver driver = iterator.next();
+      if (driverClass.equals(driver.getClass().getName())) {
+        //TODO : LENS-123 - Ability to load different instances of same driver class
+        return driver;
+      }
+    }
+    return null;
+  }
+
   public ImmutableSet<WaitingQueriesSelectionPolicy> getDriverSelectionPolicies() {
     return this.selectedDriver.getWaitingQuerySelectionPolicies();
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/e5b793c8/lens-server/src/main/java/org/apache/lens/server/query/LensServerDAO.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/LensServerDAO.java b/lens-server/src/main/java/org/apache/lens/server/query/LensServerDAO.java
index 59b1221..8a2ac19 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/LensServerDAO.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/LensServerDAO.java
@@ -85,8 +85,8 @@ public class LensServerDAO {
       + "userquery varchar(10000) not null," + "submitter varchar(255) not null," + "starttime bigint, "
       + "endtime bigint," + "result varchar(255)," + "status varchar(255), " + "metadata varchar(100000), "
       + "rows int, " + "filesize bigint, " + "errormessage varchar(10000), " + "driverstarttime bigint, "
-      + "driverendtime bigint, " + "metadataclass varchar(10000), " + "queryname varchar(255), "
-      + "submissiontime bigint" + ")";
+      + "driverendtime bigint, " + "metadataclass varchar(10000), " + "driverclass varchar(10000), "
+      + "queryname varchar(255), " + "submissiontime bigint" + ")";
     try {
       QueryRunner runner = new QueryRunner(ds);
       runner.update(sql);
@@ -109,15 +109,15 @@ public class LensServerDAO {
       Connection conn = null;
       String sql = "insert into finished_queries (handle, userquery,submitter,"
         + "starttime,endtime,result,status,metadata,rows,filesize,"
-        + "errormessage,driverstarttime,driverendtime, metadataclass, queryname, submissiontime)"
-        + " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+        + "errormessage,driverstarttime,driverendtime, metadataclass, driverclass, queryname, submissiontime)"
+        + " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
       try {
         conn = getConnection();
         QueryRunner runner = new QueryRunner();
         runner.update(conn, sql, query.getHandle(), query.getUserQuery(), query.getSubmitter(), query.getStartTime(),
           query.getEndTime(), query.getResult(), query.getStatus(), query.getMetadata(), query.getRows(),
           query.getFileSize(), query.getErrorMessage(), query.getDriverStartTime(), query.getDriverEndTime(),
-          query.getMetadataClass(), query.getQueryName(), query.getSubmissionTime());
+          query.getMetadataClass(), query.getDriverClass(), query.getQueryName(), query.getSubmissionTime());
         conn.commit();
       } finally {
         DbUtils.closeQuietly(conn);


[02/50] [abbrv] lens git commit: LENS-726 : Update 2.3 release documentation

Posted by ra...@apache.org.
LENS-726 : Update 2.3 release documentation


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

Branch: refs/heads/current-release-line
Commit: af31166398ae9655bfcd7099f8c283171f01e4cc
Parents: e9d5eaa
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Tue Aug 25 16:00:05 2015 +0530
Committer: arshad-matin <ar...@apache.org>
Committed: Tue Aug 25 16:00:05 2015 +0530

----------------------------------------------------------------------
 src/site/apt/releases/release-history.apt | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/af311663/src/site/apt/releases/release-history.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/releases/release-history.apt b/src/site/apt/releases/release-history.apt
index 16eef95..b683360 100644
--- a/src/site/apt/releases/release-history.apt
+++ b/src/site/apt/releases/release-history.apt
@@ -57,6 +57,10 @@ All Apache Lens releases
 
   * LENS-650 : Pre submit hook is separate from User Config Loader. User Config Loader is no longer an abstract class.
 
+  * LENS-651 : In /resultset api, file size is added. File size and the already existing field num-rows are only
+    populated if needed. Default value is no more -1, it's null(unpopulated).
+    Finished queries table has one more column now, so existing tables need to be updated.
+    The following sql should work: <<< ALTER TABLE finished_queries ADD filesize bigint AFTER rows>>>
 
 ** 2.2.x from 2.1.x
 


[23/50] [abbrv] lens git commit: LENS-733 : Add Helper Method for lens-regression.

Posted by ra...@apache.org.
LENS-733 : Add Helper Method for lens-regression.


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/7678a63b
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/7678a63b
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/7678a63b

Branch: refs/heads/current-release-line
Commit: 7678a63bcd41884437dabce3c47110d9876557f8
Parents: c8701a3
Author: Arshad Matin <ar...@apache.org>
Authored: Wed Sep 16 19:10:05 2015 +0530
Committer: Raghavendra Singh <ra...@apache.org>
Committed: Wed Sep 16 19:10:05 2015 +0530

----------------------------------------------------------------------
 lens-regression/pom.xml                         |   4 +
 .../core/constants/QueryInventory.java          |  57 +++++
 .../core/helpers/LensServerHelper.java          |   5 -
 .../core/helpers/MetastoreHelper.java           | 218 +++++++++++++++++-
 .../regression/core/helpers/QueryHelper.java    |  81 +++----
 .../core/helpers/ServiceManagerHelper.java      |   8 +-
 .../regression/core/helpers/SessionHelper.java  |   4 -
 .../core/testHelper/BaseTestClass.java          |  41 ++++
 .../apache/lens/regression/util/AssertUtil.java |  62 +++++-
 .../apache/lens/regression/util/HadoopUtil.java |  61 +++++
 .../org/apache/lens/regression/util/Util.java   | 220 ++++++++++++++++++-
 11 files changed, 675 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/pom.xml
----------------------------------------------------------------------
diff --git a/lens-regression/pom.xml b/lens-regression/pom.xml
index 250d008..560b4df 100644
--- a/lens-regression/pom.xml
+++ b/lens-regression/pom.xml
@@ -63,6 +63,10 @@
       <groupId>org.glassfish.jersey.media</groupId>
       <artifactId>jersey-media-multipart</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+    </dependency>
 
   </dependencies>
 

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/constants/QueryInventory.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/constants/QueryInventory.java b/lens-regression/src/main/java/org/apache/lens/regression/core/constants/QueryInventory.java
new file mode 100644
index 0000000..e41ca86
--- /dev/null
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/constants/QueryInventory.java
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.lens.regression.core.constants;
+
+public class QueryInventory {
+
+  private QueryInventory() {
+
+  }
+
+  public static final String QUERY = "cube select id,name from sample_dim where name != 'first'";
+  public static final String WRONG_QUERY = "cube select NO_ID from sample_dim where name != 'first'";
+
+  public static final String DIM_QUERY = "cube select id,name from sample_dim where name != 'first'";
+  public static final String CUBE_QUERY = "cube select sample_dim.name, measure4 from sample_cube where "
+    + "time_range_in(dt, '2014-06-24-23', '2014-06-25-00')";
+  public static final String WRONG_DIM_QUERY = "cube select NO_ID from sample_dim where name != 'first'";
+
+  public static final String HIVE_DIM_QUERY = "cube select id,name from sample_dim2 where name != 'first'";
+  public static final String HIVE_CUBE_QUERY = "cube select sample_dim.name, measure4 from sample_cube where "
+    + "time_range_in(dt, '2014-06-24-23', '2014-06-25-00')";
+
+  public static final String JDBC_CUBE_QUERY = "cube select product_id from sales where "
+    + "time_range_in(delivery_time,'2015-04-12','2015-04-13')";
+  public static final String WRONG_JDBC_CUBE_QUERY = "cube select product_id from sales where "
+    + "time_range_in(delivery_time,'2015-04-12','2015-04-14')";
+
+  public static final String WRONG_HIVE_DIM_QUERY = "cube select NO_ID from sample_dim2 where name != 'first'";
+  public static final String WRONG_HIVE_CUBE_QUERY="cube select sample_dim.name, measure4 from sample_cube where "
+    + "time_range_in(dt, '2014-07-01-00', '2014-07-25-05')";
+
+  public static final String WRONG_SYNTAX_QUERY="cube select id,name from sample_dim2 name != 'first'";
+
+  public static final String JDBC_DIM_QUERY = "cube select id,name from sample_db_dim where name != 'first'";
+  public static final String WRONG_JDBC_DIM_QUERY = "cube select NO_ID from sample_db_dim where name != 'first'";
+
+  public static final String SLEEP_FUNCTION = "CREATE TEMPORARY FUNCTION sleep AS 'hive.udf.SampleUdf'";
+  public static final String SLEEP_QUERY = "cube select sleep(name) from sample_dim where name != 'first'";
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/LensServerHelper.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/LensServerHelper.java b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/LensServerHelper.java
index 8b41dba..760c088 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/LensServerHelper.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/LensServerHelper.java
@@ -21,9 +21,7 @@ package org.apache.lens.regression.core.helpers;
 
 import java.io.IOException;
 
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.Response;
-
 import javax.xml.bind.JAXBException;
 
 import org.apache.lens.regression.util.AssertUtil;
@@ -37,9 +35,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class LensServerHelper extends ServiceManagerHelper {
 
-  private WebTarget servLens = ServiceManagerHelper.getServerLens();
-  private String sessionHandleString = ServiceManagerHelper.getSessionHandle();
-
   public LensServerHelper() {
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/MetastoreHelper.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/MetastoreHelper.java b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/MetastoreHelper.java
index aff0e8e..f60ecef 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/MetastoreHelper.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/MetastoreHelper.java
@@ -19,17 +19,20 @@
 
 package org.apache.lens.regression.core.helpers;
 
-
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+
 import javax.xml.bind.JAXBException;
 
+import org.apache.lens.api.DateTime;
 import org.apache.lens.api.StringList;
+import org.apache.lens.api.metastore.*;
 import org.apache.lens.regression.core.constants.MetastoreURL;
+import org.apache.lens.regression.core.type.FormBuilder;
 import org.apache.lens.regression.core.type.MapBuilder;
 import org.apache.lens.regression.util.AssertUtil;
+import org.apache.lens.regression.util.Util;
 import org.apache.lens.server.api.error.LensException;
 
 import lombok.extern.slf4j.Slf4j;
@@ -37,8 +40,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class MetastoreHelper extends ServiceManagerHelper {
 
-  private WebTarget servLens = ServiceManagerHelper.getServerLens();
-  private String sessionHandleString = ServiceManagerHelper.getSessionHandle();
 
   public MetastoreHelper() {
   }
@@ -149,4 +150,213 @@ public class MetastoreHelper extends ServiceManagerHelper {
     dropDatabase(dbName, sessionHandleString);
   }
 
+  public void createStorage(XStorage storage, String sessionHandleString) throws Exception {
+
+    String storageString = Util.convertObjectToXml(storage, XStorage.class, "createXStorage");
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+
+    Response response = this
+        .exec("post", MetastoreURL.METASTORE_STORAGES_URL, servLens, null, query, MediaType.APPLICATION_XML_TYPE, null,
+            storageString);
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void createStorage(XStorage storage) throws Exception {
+    createStorage(storage, sessionHandleString);
+  }
+
+  public void dropStorage(String storageName, String sessionHandleString) throws JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this
+        .exec("delete", MetastoreURL.METASTORE_STORAGES_URL + "/" + storageName, servLens, null, query,
+            MediaType.APPLICATION_XML_TYPE, null);
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void dropStorage(String storageName) throws JAXBException, LensException {
+    dropStorage(storageName, sessionHandleString);
+  }
+
+  public StringList listStorages(String sessionHandleString) throws JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("get", MetastoreURL.METASTORE_STORAGES_URL, servLens, null, query);
+    AssertUtil.assertSucceededResponse(response);
+    StringList cubeList = response.readEntity(StringList.class);
+    return cubeList;
+  }
+
+  public StringList listStorages() throws JAXBException, LensException {
+    return listStorages(sessionHandleString);
+  }
+
+  public void createCube(XCube cube, String sessionHandleString) throws Exception {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    String cubeString = Util.convertObjectToXml(cube, XCube.class, "createXCube");
+    Response response = this
+        .exec("post", MetastoreURL.METASTORE_CUBES_URL, servLens, null, query, MediaType.APPLICATION_XML_TYPE, null,
+            cubeString);
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void createCube(XCube cube) throws Exception {
+    createCube(cube, sessionHandleString);
+  }
+
+  public void createFacts(XFactTable facts, String sessionHandleString) throws Exception {
+    String factString = Util.convertObjectToXml(facts, XFactTable.class, "createXFactTable");
+
+    FormBuilder formData = new FormBuilder();
+    formData.add("sessionid", sessionHandleString);
+    formData.add("fact", factString);
+
+    Response response = this
+        .exec("post", MetastoreURL.METASTORE_FACTS_URL, servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
+            MediaType.APPLICATION_XML, formData.getForm());
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void createFacts(XFactTable facts) throws Exception {
+    createFacts(facts, sessionHandleString);
+  }
+
+  public StringList listCubes(String type, String sessionHandleString) throws Exception {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    if (type != null) {
+      query.put("type", type);
+    }
+    Response response = this.exec("get", MetastoreURL.METASTORE_CUBES_URL, servLens, null, query);
+    AssertUtil.assertSucceededResponse(response);
+    StringList cubeList = response.readEntity(StringList.class);
+    return cubeList;
+  }
+
+  public StringList listCubes(String type) throws Exception {
+    return listCubes(type, sessionHandleString);
+  }
+
+  public StringList listCubes() throws Exception {
+    return listCubes(null);
+  }
+
+  public XCube getCube(String cubeName, String sessionHandleString)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("get", MetastoreURL.METASTORE_CUBES_URL + "/" + cubeName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE);
+    AssertUtil.assertSucceededResponse(response);
+    String responseString = response.readEntity(String.class);
+    log.info(responseString);
+    XCube cube = (XCube) Util.extractObject(responseString, XCube.class);
+    return cube;
+  }
+
+  public XCube getCube(String cubeName)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    return getCube(cubeName, sessionHandleString);
+  }
+
+  public XFactTable getFact(String factName, String sessionHandleString)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("get", MetastoreURL.METASTORE_FACTS_URL + "/" + factName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE);
+    AssertUtil.assertSucceededResponse(response);
+    String responseString = response.readEntity(String.class);
+    log.info(responseString);
+    XFactTable fact = (XFactTable) Util.extractObject(responseString, XFactTable.class);
+    return fact;
+  }
+
+  public XFactTable getFact(String factName)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    return getFact(factName, sessionHandleString);
+  }
+
+  public XDimension getDimension(String dimName, String sessionHandleString)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("get", MetastoreURL.METASTORE_DIMENSIONS_URL + "/" + dimName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE);
+    AssertUtil.assertSucceededResponse(response);
+    String responseString = response.readEntity(String.class);
+    log.info(responseString);
+    XDimension dim = (XDimension) Util.extractObject(responseString, XDimension.class);
+    return dim;
+  }
+
+  public XDimension getDimension(String dimName)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    return getDimension(dimName, sessionHandleString);
+  }
+
+  public XDimensionTable getDimensionTable(String dimName, String sessionHandleString)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("get", MetastoreURL.METASTORE_DIMTABLES_URL + "/" + dimName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE);
+    AssertUtil.assertSucceededResponse(response);
+    String responseString = response.readEntity(String.class);
+    log.info(responseString);
+    XDimensionTable dim = (XDimensionTable) Util.extractObject(responseString, XDimensionTable.class);
+    return dim;
+  }
+
+  public XDimensionTable getDimensionTable(String dimName)
+    throws InstantiationException, IllegalAccessException, JAXBException, LensException {
+    return getDimensionTable(dimName, sessionHandleString);
+  }
+
+  public void updateCube(XCube cube, String cubeName, String sessionHandleString) throws Exception {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    String cubeString = Util.convertObjectToXml(cube, XCube.class, "createXCube");
+    Response response = this.exec("put", MetastoreURL.METASTORE_CUBES_URL + "/" + cubeName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE, null, cubeString);
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void updateCube(XCube cube, String cubeName) throws Exception {
+    updateCube(cube, cubeName, sessionHandleString);
+  }
+
+  public void dropCube(String cubeName, String sessionHandleString) throws JAXBException, LensException {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    Response response = this.exec("delete", MetastoreURL.METASTORE_CUBES_URL + "/" + cubeName, servLens, null, query,
+        MediaType.APPLICATION_XML_TYPE, null);
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void dropCube(String cubeName) throws JAXBException, LensException {
+    dropCube(cubeName, sessionHandleString);
+  }
+
+  public void createDimTable(XDimensionTable dt, String sessionHandleString) throws Exception {
+    String dimTable = Util.convertObjectToXml(dt, XDimensionTable.class, "createDimensionTable");
+
+    FormBuilder formData = new FormBuilder();
+    formData.add("sessionid", sessionHandleString);
+    formData.add("dimensionTable", dimTable);
+
+    Response response = this
+        .exec("post", MetastoreURL.METASTORE_DIMTABLES_URL, servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
+            MediaType.APPLICATION_XML, formData.getForm());
+    AssertUtil.assertSucceeded(response);
+  }
+
+  public void createDimTable(XDimensionTable dt) throws Exception {
+    createDimTable(dt, sessionHandleString);
+  }
+
+  public void getLatestDate(String sessionHandleString) throws Exception {
+    MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
+    query.put("timeDimension", "event_time");
+    Response response = this
+        .exec("get", "/metastore/cubes/rrcube/latestdate", servLens, null, query, MediaType.APPLICATION_XML_TYPE, null,
+            query);
+    DateTime dt = (DateTime) Util.getObject(response.readEntity(String.class), DateTime.class);
+  }
+
+  public void getLatestDate() throws Exception {
+    getLatestDate(sessionHandleString);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/QueryHelper.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/QueryHelper.java b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/QueryHelper.java
index 70cad28..37fb703 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/QueryHelper.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/QueryHelper.java
@@ -21,16 +21,13 @@ package org.apache.lens.regression.core.helpers;
 
 import java.util.List;
 
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-
 import javax.xml.bind.JAXBException;
 
 import org.apache.lens.api.LensConf;
 import org.apache.lens.api.query.*;
 import org.apache.lens.api.result.LensAPIResult;
-import org.apache.lens.api.result.QueryCostTO;
 import org.apache.lens.regression.core.constants.QueryURL;
 import org.apache.lens.regression.core.type.FormBuilder;
 import org.apache.lens.regression.core.type.MapBuilder;
@@ -48,8 +45,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class QueryHelper extends ServiceManagerHelper {
 
-  private WebTarget servLens = ServiceManagerHelper.getServerLens();
-  private String sessionHandleString = ServiceManagerHelper.getSessionHandle();
 
   public QueryHelper() {
   }
@@ -58,6 +53,7 @@ public class QueryHelper extends ServiceManagerHelper {
     super(envFileName);
   }
 
+
   /**
    * Execute with conf
    *
@@ -67,8 +63,8 @@ public class QueryHelper extends ServiceManagerHelper {
    * @param conf
    * @return the query Handle
    */
-  public QueryHandle executeQuery(String queryString, String queryName, String sessionHandleString, String conf) throws
-      InstantiationException, IllegalAccessException, JAXBException, LensException {
+  public LensAPIResult executeQuery(String queryString, String queryName, String sessionHandleString,
+      String conf) throws InstantiationException, IllegalAccessException, JAXBException, LensException {
     FormBuilder formData = new FormBuilder();
     formData.add("sessionid", sessionHandleString);
     formData.add("query", queryString);
@@ -79,30 +75,24 @@ public class QueryHelper extends ServiceManagerHelper {
     }
     Response response = this.exec("post", QueryURL.QUERY_URL, servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
         MediaType.APPLICATION_XML, formData.getForm());
-    AssertUtil.assertSucceededResponse(response);
     String queryHandleString = response.readEntity(String.class);
     log.info("QueryHandle String:{}", queryHandleString);
-    LensAPIResult successResponse = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
-    QueryHandle queryHandle = (QueryHandle) successResponse.getData();
-    if (queryHandle == null) {
-      throw new LensException("Query Execute Failed");
-    }
-    log.info("Query Handle : {}", queryHandle);
-    return queryHandle;
+    LensAPIResult result = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
+    return result;
   }
 
-  public QueryHandle executeQuery(String queryString, String queryName, String sessionHandleString) throws
+  public LensAPIResult executeQuery(String queryString, String queryName, String sessionHandleString) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQuery(queryString, queryName, sessionHandleString,
         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><conf />");
   }
 
-  public QueryHandle executeQuery(String queryString, String queryName) throws
+  public LensAPIResult executeQuery(String queryString, String queryName) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQuery(queryString, queryName, sessionHandleString);
   }
 
-  public QueryHandle executeQuery(String queryString) throws
+  public LensAPIResult executeQuery(String queryString) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQuery(queryString, null);
   }
@@ -118,7 +108,7 @@ public class QueryHelper extends ServiceManagerHelper {
    * @return the queryHandleWithResultSet
    */
 
-  public QueryHandleWithResultSet executeQueryTimeout(String queryString, String timeout, String queryName,
+  public LensAPIResult executeQueryTimeout(String queryString, String timeout, String queryName,
       String sessionHandleString, String conf) throws InstantiationException, IllegalAccessException, JAXBException,
       LensException {
     FormBuilder formData = new FormBuilder();
@@ -134,35 +124,29 @@ public class QueryHelper extends ServiceManagerHelper {
     }
     Response response = this.exec("post", QueryURL.QUERY_URL, servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
         MediaType.APPLICATION_XML, formData.getForm());
-    AssertUtil.assertSucceededResponse(response);
     String queryHandleString = response.readEntity(String.class);
     log.info("QueryHandle String:{}", queryHandleString);
-    LensAPIResult successResponse = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
-    QueryHandleWithResultSet queryHandleWithResultSet = (QueryHandleWithResultSet) successResponse.getData();
-    if (queryHandleWithResultSet==null) {
-      throw new LensException("Query Execute Failed");
-    }
-    log.info("Query Handle with ResultSet : {}", queryHandleWithResultSet);
-    return queryHandleWithResultSet;
+    LensAPIResult result = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
+    return result;
   }
 
-  public QueryHandleWithResultSet executeQueryTimeout(String queryString, String timeout, String queryName,
+  public LensAPIResult executeQueryTimeout(String queryString, String timeout, String queryName,
       String sessionHandleString) throws InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQueryTimeout(queryString, timeout, queryName, sessionHandleString,
         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><conf />");
   }
 
-  public QueryHandleWithResultSet executeQueryTimeout(String queryString, String timeout, String queryName) throws
+  public LensAPIResult executeQueryTimeout(String queryString, String timeout, String queryName) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQueryTimeout(queryString, timeout, queryName, sessionHandleString);
   }
 
-  public QueryHandleWithResultSet executeQueryTimeout(String queryString, String timeout) throws
+  public LensAPIResult executeQueryTimeout(String queryString, String timeout) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQueryTimeout(queryString, timeout, null);
   }
 
-  public QueryHandleWithResultSet executeQueryTimeout(String queryString) throws
+  public LensAPIResult executeQueryTimeout(String queryString) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return executeQueryTimeout(queryString, null);
   }
@@ -178,7 +162,7 @@ public class QueryHelper extends ServiceManagerHelper {
    * @return the query Handle
    */
 
-  public QueryHandle executeQuery(String queryString, String queryName, String user, String sessionHandleString,
+  public LensAPIResult executeQuery(String queryString, String queryName, String user, String sessionHandleString,
       LensConf conf) throws JAXBException, InstantiationException, IllegalAccessException, LensException {
 
     FormBuilder formData = new FormBuilder();
@@ -196,12 +180,10 @@ public class QueryHelper extends ServiceManagerHelper {
             MediaType.APPLICATION_XML_TYPE));
     Response response = this.exec("post", "/queryapi/queries", servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
         MediaType.APPLICATION_XML, formData.getForm());
-    AssertUtil.assertSucceededResponse(response);
     String queryHandleString = response.readEntity(String.class);
     log.info("QueryHandle String:{}", queryHandleString);
-    LensAPIResult successResponse = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
-    QueryHandle queryHandle = (QueryHandle) successResponse.getData();
-    return queryHandle;
+    LensAPIResult result = (LensAPIResult) Util.getObject(queryHandleString, LensAPIResult.class);
+    return result;
   }
 
   /**
@@ -213,7 +195,7 @@ public class QueryHelper extends ServiceManagerHelper {
    * @return the query Plan
    */
 
-  public QueryPlan explainQuery(String queryString, String sessionHandleString, String conf) throws
+  public LensAPIResult explainQuery(String queryString, String sessionHandleString, String conf) throws
       JAXBException, InstantiationException, IllegalAccessException, LensException {
     FormBuilder formData = new FormBuilder();
     formData.add("sessionid", sessionHandleString);
@@ -224,21 +206,19 @@ public class QueryHelper extends ServiceManagerHelper {
             MediaType.APPLICATION_XML_TYPE));
     Response response = this.exec("post", "/queryapi/queries", servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
         MediaType.APPLICATION_XML, formData.getForm());
-    AssertUtil.assertSucceededResponse(response);
     String queryPlanString = response.readEntity(String.class);
     log.info("QueryPlan String:{}", queryPlanString);
-    LensAPIResult successResponse = (LensAPIResult) Util.getObject(queryPlanString, LensAPIResult.class);
-    QueryPlan queryPlan = (QueryPlan) successResponse.getData();
-    return queryPlan;
+    LensAPIResult result = (LensAPIResult) Util.getObject(queryPlanString, LensAPIResult.class);
+    return result;
   }
 
-  public QueryPlan explainQuery(String queryString, String sessionHandleString) throws
+  public LensAPIResult explainQuery(String queryString, String sessionHandleString) throws
       JAXBException, InstantiationException, IllegalAccessException, LensException {
     return explainQuery(queryString, sessionHandleString,
         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><conf />");
   }
 
-  public QueryPlan explainQuery(String queryString) throws
+  public LensAPIResult explainQuery(String queryString) throws
       JAXBException, InstantiationException, IllegalAccessException, LensException {
     return explainQuery(queryString, sessionHandleString);
   }
@@ -252,7 +232,7 @@ public class QueryHelper extends ServiceManagerHelper {
    * @return the Estimate result
    */
 
-  public QueryCostTO estimateQuery(String queryString, String sessionHandleString, String conf) throws
+  public LensAPIResult estimateQuery(String queryString, String sessionHandleString, String conf) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     FormBuilder formData = new FormBuilder();
     formData.add("sessionid", sessionHandleString);
@@ -261,24 +241,19 @@ public class QueryHelper extends ServiceManagerHelper {
     formData.add("conf", conf);
     Response response = this.exec("post", QueryURL.QUERY_URL, servLens, null, null, MediaType.MULTIPART_FORM_DATA_TYPE,
         MediaType.APPLICATION_XML, formData.getForm());
-    AssertUtil.assertSucceededResponse(response);
     String queryCostString = response.readEntity(String.class);
     log.info("QueryCost String:{}", queryCostString);
-    LensAPIResult successResponse = (LensAPIResult) Util.getObject(queryCostString, LensAPIResult.class);
-    QueryCostTO queryCostTO = (QueryCostTO) successResponse.getData();
-    if (queryCostTO == null) {
-      throw new LensException("Estimate Failed");
-    }
-    return queryCostTO;
+    LensAPIResult result = (LensAPIResult) Util.getObject(queryCostString, LensAPIResult.class);
+    return result;
   }
 
-  public QueryCostTO estimateQuery(String queryString, String sessionHandleString) throws
+  public LensAPIResult estimateQuery(String queryString, String sessionHandleString) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return estimateQuery(queryString, sessionHandleString,
         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><conf />");
   }
 
-  public QueryCostTO estimateQuery(String queryString) throws
+  public LensAPIResult estimateQuery(String queryString) throws
       InstantiationException, IllegalAccessException, JAXBException, LensException {
     return estimateQuery(queryString, sessionHandleString);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/ServiceManagerHelper.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/ServiceManagerHelper.java b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/ServiceManagerHelper.java
index b14b00b..feddb0f 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/ServiceManagerHelper.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/ServiceManagerHelper.java
@@ -57,8 +57,8 @@ public abstract class ServiceManagerHelper {
   private static final String LENS_SERVER_HDFS_URL = "lens.server.hdfsurl";
   private static final String LENS_CURRENT_DB = "lens.server.currentDB";
 
-  private static String sessionHandleString;
-  private static WebTarget servLens;
+  protected static String sessionHandleString;
+  protected static WebTarget servLens;
 
   protected String baseUrl;
   protected String adminUrl;
@@ -163,10 +163,10 @@ public abstract class ServiceManagerHelper {
     MapBuilder query = new MapBuilder("sessionid", sessionHandleString);
     Response response = this.exec("delete", SessionURL.SESSION_BASE_URL, ServiceManagerHelper.servLens, null, query);
     APIResult result = response.readEntity(APIResult.class);
-    if (result.getStatus() == APIResult.Status.SUCCEEDED) {
+    if (result.getStatus() != APIResult.Status.SUCCEEDED) {
       throw new LensException("Status should be SUCCEEDED");
     }
-    if (response.getStatus() == 200) {
+    if (response.getStatus() != 200) {
       throw new LensException("Status code should be 200");
     }
     if (result.getMessage() == null) {

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/SessionHelper.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/SessionHelper.java b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/SessionHelper.java
index e7bc700..3c640e2 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/SessionHelper.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/helpers/SessionHelper.java
@@ -22,10 +22,8 @@ package org.apache.lens.regression.core.helpers;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-
 import javax.xml.bind.JAXBException;
 
 import org.apache.lens.api.APIResult;
@@ -40,8 +38,6 @@ import lombok.extern.slf4j.Slf4j;
 @Slf4j
 public class SessionHelper extends ServiceManagerHelper {
 
-  private WebTarget servLens = ServiceManagerHelper.getServerLens();
-  private String sessionHandleString = ServiceManagerHelper.getSessionHandle();
 
   public SessionHelper() {
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/core/testHelper/BaseTestClass.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/core/testHelper/BaseTestClass.java b/lens-regression/src/main/java/org/apache/lens/regression/core/testHelper/BaseTestClass.java
index 2985af4..f442983 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/core/testHelper/BaseTestClass.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/core/testHelper/BaseTestClass.java
@@ -16,8 +16,49 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.lens.regression.core.testHelper;
 
+import org.apache.lens.regression.core.helpers.LensHelper;
+import org.apache.lens.regression.core.helpers.LensServerHelper;
+import org.apache.lens.regression.core.helpers.MetastoreHelper;
+import org.apache.lens.regression.core.helpers.QueryHelper;
+import org.apache.lens.regression.core.helpers.SessionHelper;
+
 public class BaseTestClass {
 
+  private LensHelper lensHelper;
+  private QueryHelper qHelper;
+  private MetastoreHelper mHelper;
+  private SessionHelper sHelper;
+  private LensServerHelper lens;
+
+  public static final String LENS_PROPERTIES = "lens.properties";
+
+  public BaseTestClass() {
+
+    lensHelper = new LensHelper(LENS_PROPERTIES);
+    qHelper = lensHelper.getQueryHelper();
+    mHelper = lensHelper.getMetastoreHelper();
+    sHelper = lensHelper.getSessionHelper();
+    lens = lensHelper.getServerHelper();
+  }
+
+  public QueryHelper getQueryHelper() {
+    return qHelper;
+  }
+
+  public MetastoreHelper getMetastoreHelper() {
+    return mHelper;
+  }
+
+  public SessionHelper getSessionHelper() {
+    return sHelper;
+  }
+
+  public LensServerHelper getLensServerHelper() {
+    return lens;
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/util/AssertUtil.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/util/AssertUtil.java b/lens-regression/src/main/java/org/apache/lens/regression/util/AssertUtil.java
index 62bd160..ea36858 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/util/AssertUtil.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/util/AssertUtil.java
@@ -22,8 +22,13 @@ package org.apache.lens.regression.util;
 import javax.ws.rs.core.Response;
 
 import org.apache.lens.api.APIResult;
+import org.apache.lens.api.result.LensAPIResult;
+import org.apache.lens.api.result.LensErrorTO;
 import org.apache.lens.server.api.error.LensException;
 
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
 public class AssertUtil {
 
   private AssertUtil() {
@@ -37,11 +42,11 @@ public class AssertUtil {
    * @throws LensException
    */
   public static void assertSucceeded(Response response) throws LensException {
-    if (response.getStatus() == 200) {
+    if (response.getStatus() != 200) {
       throw new LensException("Status code should be 200");
     }
     APIResult result = Util.getApiResult(response);
-    if (result.getStatus() == APIResult.Status.SUCCEEDED) {
+    if (result.getStatus() != APIResult.Status.SUCCEEDED) {
       throw new LensException("Status should be SUCCEEDED");
     }
     if (result.getMessage() == null) {
@@ -56,13 +61,19 @@ public class AssertUtil {
    * @throws LensException
    */
   public static void assertSucceededResponse(Response response) throws LensException {
-    if (response.getStatus() == 200) {
+    if (response.getStatus() != 200) {
       throw new LensException("Status code should be 200");
     }
   }
 
+  public static void assertSucceededResponse(Response response, int expected) throws LensException {
+    if (response.getStatus() != expected) {
+      throw new LensException("Status code should be " + expected);
+    }
+  }
+
   public static void assertGoneResponse(Response response) throws LensException {
-    if (response.getStatus() == 410) {
+    if (response.getStatus() != 410) {
       throw new LensException("Status code should be 410");
     }
   }
@@ -74,7 +85,7 @@ public class AssertUtil {
    * @throws LensException
    */
   public static void assertFailedResponse(Response response) throws LensException {
-    if (response.getStatus() == 404) {
+    if (response.getStatus() != 404) {
       throw new LensException("Status code should be 404");
     }
   }
@@ -86,11 +97,11 @@ public class AssertUtil {
    * @throws LensException
    */
   public static void assertFailed(Response response) throws LensException {
-    if (response.getStatus() == 400) {
+    if (response.getStatus() != 400) {
       throw new LensException("Status code should be 400");
     }
     APIResult result = Util.getApiResult(response);
-    if (result.getStatus() == APIResult.Status.FAILED) {
+    if (result.getStatus() != APIResult.Status.FAILED) {
       throw new LensException("Status should be FAILED");
     }
     if (result.getMessage() == null) {
@@ -125,10 +136,45 @@ public class AssertUtil {
    */
 
   public static void assertInternalServerError(Response response) throws LensException {
-    if (response.getStatus() == 500) {
+    if (response.getStatus() != 500) {
       throw new LensException("Status code should be 500");
     }
 
   }
 
+  public static void validateFailedResponse(int errorCode, String errorMessage, boolean payLoad, Response response,
+      int httpResponseCode) throws InstantiationException, IllegalAccessException, LensException {
+    String queryHandleString = response.readEntity(String.class);
+    log.info(queryHandleString);
+    @SuppressWarnings("unchecked") LensAPIResult errorResponse = (LensAPIResult) Util
+        .getObject(queryHandleString, LensAPIResult.class);
+    LensErrorTO error = errorResponse.getLensErrorTO();
+    LensErrorTO expectedError = null;
+    if (payLoad) {
+      expectedError = LensErrorTO.composedOf(errorCode, errorMessage, "nothing", error.getPayload());
+    } else {
+      expectedError = LensErrorTO.composedOf(errorCode, errorMessage, "nothing");
+    }
+    log.info("expected Error-: " + expectedError);
+    log.info("actual Error-: " + error);
+    if (!error.equals(expectedError)) {
+      throw new LensException("Wrong Error Response");
+    }
+    if (!errorResponse.areValidStackTracesPresent()) {
+      throw new LensException("StackTrace should be present");
+    }
+    if (payLoad) {
+      if (error.getPayload() == null) {
+        throw new LensException("Payload should not be null");
+      }
+    } else {
+      if (error.getPayload() != null) {
+        throw new LensException("Payload should be null");
+      }
+    }
+    if (errorResponse.isSuccessResult()) {
+      throw new LensException("SuccessResponse should be false");
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/util/HadoopUtil.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/util/HadoopUtil.java b/lens-regression/src/main/java/org/apache/lens/regression/util/HadoopUtil.java
new file mode 100644
index 0000000..a4ae5c1
--- /dev/null
+++ b/lens-regression/src/main/java/org/apache/lens/regression/util/HadoopUtil.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.lens.regression.util;
+
+import java.io.IOException;
+
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class HadoopUtil {
+
+  private HadoopUtil() {
+
+  }
+
+  static String rmIp = Util.getProperty("lens.remote.host");
+
+  public static Configuration getHadoopConfiguration() {
+    Configuration conf = new Configuration();
+    conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
+    conf.set("fs.default.name", Util.getProperty("lens.server.hdfsurl"));
+    return conf;
+  }
+
+  public static void uploadJars(String sourcePath, String hdfsDestinationPath) throws IOException {
+
+    Configuration conf = HadoopUtil.getHadoopConfiguration();
+    FileSystem fs = FileSystem.get(conf);
+
+    Path localFilePath = new Path(sourcePath);
+    Path hdfsFilePath = new Path(hdfsDestinationPath);
+
+    log.info("Copying " + sourcePath + " to " + hdfsDestinationPath);
+    fs.copyFromLocalFile(localFilePath, hdfsFilePath);
+    log.info("Copied Successfully " + sourcePath + " to " + hdfsDestinationPath);
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/7678a63b/lens-regression/src/main/java/org/apache/lens/regression/util/Util.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/main/java/org/apache/lens/regression/util/Util.java b/lens-regression/src/main/java/org/apache/lens/regression/util/Util.java
index 0e531e0..7bda529 100644
--- a/lens-regression/src/main/java/org/apache/lens/regression/util/Util.java
+++ b/lens-regression/src/main/java/org/apache/lens/regression/util/Util.java
@@ -18,28 +18,55 @@
  */
 package org.apache.lens.regression.util;
 
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+
 import java.io.*;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.*;
+import java.util.Map.Entry;
 
 import javax.ws.rs.core.Response;
 import javax.xml.bind.*;
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
 
 import org.apache.lens.api.APIResult;
 import org.apache.lens.api.StringList;
 import org.apache.lens.api.jaxb.LensJAXBContext;
 import org.apache.lens.api.metastore.ObjectFactory;
+import org.apache.lens.api.metastore.XProperties;
+import org.apache.lens.api.metastore.XProperty;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 import com.jcraft.jsch.*;
-import lombok.extern.slf4j.Slf4j;
 
 
+import lombok.extern.slf4j.Slf4j;
+
 @Slf4j
 public class Util {
 
   private static final String PROPERTY_FILE = "lens.properties";
   private static Properties properties;
+  private static String localFilePath = "src/test/resources/";
+  private static String localFile;
+  private static String backupFile;
+  private static String remoteFile;
 
   private Util() {
 
@@ -127,13 +154,14 @@ public class Util {
   }
 
   @SuppressWarnings("unchecked")
-  public static <T> Object extractObject(String queryString, Class<T> c) throws
-    InstantiationException, IllegalAccessException {
+  public static <T> Object extractObject(String queryString, Class<T> c)
+    throws InstantiationException, IllegalAccessException {
     JAXBContext jaxbContext = null;
     Unmarshaller unmarshaller = null;
     StringReader reader = new StringReader(queryString);
     try {
-      jaxbContext = new LensJAXBContext(ObjectFactory.class) {};
+      jaxbContext = new LensJAXBContext(ObjectFactory.class) {
+      };
       unmarshaller = jaxbContext.createUnmarshaller();
       return (T) ((JAXBElement<?>) unmarshaller.unmarshal(reader)).getValue();
     } catch (JAXBException e) {
@@ -143,8 +171,8 @@ public class Util {
   }
 
   @SuppressWarnings("unchecked")
-  public static <T> Object getObject(String queryString, Class<T> c) throws
-    InstantiationException, IllegalAccessException {
+  public static <T> Object getObject(String queryString, Class<T> c)
+    throws InstantiationException, IllegalAccessException {
     JAXBContext jaxbContext = null;
     Unmarshaller unmarshaller = null;
     StringReader reader = new StringReader(queryString);
@@ -159,8 +187,8 @@ public class Util {
   }
 
   @SuppressWarnings("unchecked")
-  public static <T> String convertObjectToXml(T object, Class<T> clazz, String functionName) throws
-    SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
+  public static <T> String convertObjectToXml(T object, Class<T> clazz, String functionName)
+    throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException,
     InvocationTargetException {
     JAXBElement<T> root = null;
     StringWriter stringWriter = new StringWriter();
@@ -209,4 +237,180 @@ public class Util {
     return stringListToMap(stringList);
   }
 
+  public static void changeConfig(HashMap<String, String> map, String remotePath) throws Exception {
+    String fileName;
+    remoteFile = remotePath;
+
+    Path p = Paths.get(remoteFile);
+
+    fileName = p.getFileName().toString();
+    backupFile = localFilePath + "backup-" + fileName;
+    localFile = localFilePath + fileName;
+    log.info("Copying " + remoteFile + " to " + localFile);
+    remoteFile("get", remoteFile, localFile);
+    File locfile = new File(localFile);
+    File remfile = new File(backupFile);
+    Files.copy(locfile.toPath(), remfile.toPath(), REPLACE_EXISTING);
+
+    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+    Document doc = docBuilder.parse(new FileInputStream(localFile));
+    doc.normalize();
+
+    NodeList rootNodes = doc.getElementsByTagName("configuration");
+    Node root = rootNodes.item(0);
+    Element rootElement = (Element) root;
+    NodeList property = rootElement.getElementsByTagName("property");
+
+    for (int i = 0; i < property.getLength(); i++)   //Deleting redundant properties from the document
+    {
+      Node prop = property.item(i);
+      Element propElement = (Element) prop;
+      Node propChild = propElement.getElementsByTagName("name").item(0);
+
+      Element nameElement = (Element) propChild;
+      if (map.containsKey(nameElement.getTextContent())) {
+        rootElement.removeChild(prop);
+        i--;
+      }
+
+    }
+
+    Iterator<Entry<String, String>> ab = map.entrySet().iterator();
+    while (ab.hasNext()) {
+      Entry<String, String> entry = ab.next();
+      String propertyName = entry.getKey();
+      String propertyValue = entry.getValue();
+      System.out.println(propertyName + " " + propertyValue + "\n");
+      Node newNode = doc.createElement("property");
+      rootElement.appendChild(newNode);
+      Node newName = doc.createElement("name");
+      Element newNodeElement = (Element) newNode;
+
+      newName.setTextContent(propertyName);
+      newNodeElement.appendChild(newName);
+
+      Node newValue = doc.createElement("value");
+      newValue.setTextContent(propertyValue);
+      newNodeElement.appendChild(newValue);
+    }
+    prettyPrint(doc);
+    remoteFile("put", remoteFile, localFile);
+  }
+
+  /*
+   * function to save the changes in the document
+   */
+  public static final void prettyPrint(Document xml) throws TransformerFactoryConfigurationError, TransformerException {
+    xml.normalize();
+    Transformer transformer = TransformerFactory.newInstance().newTransformer();
+    Result output = new StreamResult(new File(localFile));
+    Source input = new DOMSource(xml);
+    transformer.transform(input, output);
+  }
+
+  /*
+   * function to download or upload a file to a remote server
+   */
+  public static void remoteFile(String function, String remotePath, String localPath)
+    throws JSchException, SftpException {
+    String serverUrl = getProperty("lens.remote.host");
+    String serverUname = getProperty("lens.remote.username");
+    String serverPass = getProperty("lens.remote.password");
+
+    JSch jsch = new JSch();
+    Session session = jsch.getSession(serverUname, serverUrl);
+
+    UserInfo ui = null;
+    session.setUserInfo(ui);
+    session.setPassword(serverPass);
+
+    Properties config = new Properties();
+    config.put("StrictHostKeyChecking", "no");
+    session.setConfig(config);
+    session.connect();
+
+    Channel channel = session.openChannel("sftp");
+    channel.connect();
+
+    ChannelSftp sftpChannel = (ChannelSftp) channel;
+    if (function.equals("get")) {
+      sftpChannel.get(remotePath, localPath);
+    } else if (function.equals("put")) {
+      sftpChannel.put(localPath, remotePath);
+    }
+    sftpChannel.exit();
+    session.disconnect();
+
+  }
+
+  public static void changeConfig(String remotePath) throws JSchException, SftpException {
+    String fileName;
+    remoteFile = remotePath;
+
+    Path p = Paths.get(remoteFile);
+
+    fileName = p.getFileName().toString();
+    backupFile = localFilePath + "backup-" + fileName;
+
+    log.info("Copying " + backupFile + " to " + remoteFile);
+    remoteFile("put", remoteFile, backupFile);
+  }
+
+  public static Map<String, String> mapFromXProperties(XProperties xProperties) {
+    Map<String, String> properties = new HashMap<String, String>();
+    if (xProperties != null && xProperties.getProperty() != null
+      && !xProperties.getProperty().isEmpty()) {
+      for (XProperty xp : xProperties.getProperty()) {
+        properties.put(xp.getName(), xp.getValue());
+      }
+    }
+    return properties;
+  }
+
+  public static XProperties xPropertiesFromMap(Map<String, String> map) {
+    ObjectFactory xCF = new ObjectFactory();
+    if (map != null && !map.isEmpty()) {
+      XProperties xp = xCF.createXProperties();
+      List<XProperty> xpList = xp.getProperty();
+      for (Map.Entry<String, String> e : map.entrySet()) {
+        XProperty property = xCF.createXProperty();
+        property.setName(e.getKey());
+        property.setValue(e.getValue());
+        xpList.add(property);
+      }
+
+      return xp;
+    }
+    return null;
+  }
+
+  public static List<XProperty> xPropertyFromMap(Map<String, String> map) {
+    List<XProperty> xpList = new ArrayList<XProperty>();
+    if (map != null && !map.isEmpty()) {
+      for (Map.Entry<String, String> e : map.entrySet()) {
+        XProperty property = new XProperty();
+        property.setName(e.getKey());
+        property.setValue(e.getValue());
+        xpList.add(property);
+      }
+    }
+    return xpList;
+  }
+
+  public static XMLGregorianCalendar getXMLGregorianCalendar(Date d) {
+    if (d == null) {
+      return null;
+    }
+
+    GregorianCalendar c1 = new GregorianCalendar();
+    c1.setTime(d);
+    try {
+      return DatatypeFactory.newInstance().newXMLGregorianCalendar(c1);
+    } catch (DatatypeConfigurationException e) {
+      log.info("Error converting date " + d, e);
+      return null;
+    }
+  }
+
 }


[47/50] [abbrv] lens git commit: LENS-739 : Generate udf jar for lens-regression

Posted by ra...@apache.org.
LENS-739 : Generate udf jar for lens-regression


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

Branch: refs/heads/current-release-line
Commit: d4d4aa26a84f489eeef1cc9008660ac3ad570fa7
Parents: 2d7948d
Author: Archana H <ar...@gmail.com>
Authored: Thu Oct 8 16:02:51 2015 +0530
Committer: Arshad Matin <ar...@apache.org>
Committed: Thu Oct 8 16:02:51 2015 +0530

----------------------------------------------------------------------
 lens-regression/pom.xml                         | 38 +++++++++++++++++++-
 .../src/additional/java/SampleUdf.java          | 17 +++++++++
 2 files changed, 54 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/d4d4aa26/lens-regression/pom.xml
----------------------------------------------------------------------
diff --git a/lens-regression/pom.xml b/lens-regression/pom.xml
index 560b4df..aa44a48 100644
--- a/lens-regression/pom.xml
+++ b/lens-regression/pom.xml
@@ -67,7 +67,43 @@
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-common</artifactId>
     </dependency>
-
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-exec</artifactId>
+    </dependency>
   </dependencies>
 
+  <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>hive-udf-jars</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <configuration>
+                            <target>
+                                <property name="build.compiler" value="extJavac"/>
+                                <property name="compile_classpath" refid="maven.compile.classpath"/>
+                                <mkdir dir="${project.build.directory}/additional-classes"/>
+                                <javac includeantruntime="false" srcdir="src/additional/java"
+                                       destdir="${project.build.directory}/additional-classes" classpath="${compile_classpath}"/>
+                                <mkdir dir="${project.build.directory}/testjars"/>
+                                <jar destfile="${project.build.directory}/testjars/hiveudftest.jar">
+                                    <fileset dir="${project.build.directory}/additional-classes" includes="SampleUdf.class"/>
+                                </jar>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+
 </project>

http://git-wip-us.apache.org/repos/asf/lens/blob/d4d4aa26/lens-regression/src/additional/java/SampleUdf.java
----------------------------------------------------------------------
diff --git a/lens-regression/src/additional/java/SampleUdf.java b/lens-regression/src/additional/java/SampleUdf.java
new file mode 100644
index 0000000..2c3e667
--- /dev/null
+++ b/lens-regression/src/additional/java/SampleUdf.java
@@ -0,0 +1,17 @@
+import org.apache.hadoop.hive.ql.exec.UDF;
+import org.apache.hadoop.io.Text;
+
+public final class SampleUdf extends UDF {
+    public Text evaluate(final Text s, Text sleepTime) throws InterruptedException {
+
+        if(sleepTime!=null){
+            Thread.sleep(Long.parseLong(sleepTime.toString()));
+        }else{
+            Thread.sleep(180000);
+        }
+
+        if (s == null) { return null; }
+
+        return new Text(s.toString().toLowerCase());
+    }
+}
\ No newline at end of file


[07/50] [abbrv] lens git commit: LENS-745 : Fix dropping latest partition from timeline

Posted by ra...@apache.org.
LENS-745 : Fix dropping latest partition from timeline


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/86f251a7
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/86f251a7
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/86f251a7

Branch: refs/heads/current-release-line
Commit: 86f251a75b3a010a795f29be982ee19d9b2ba780
Parents: 2901b4b
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Mon Aug 31 10:19:56 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Mon Aug 31 10:19:56 2015 +0530

----------------------------------------------------------------------
 .../lens/cube/metadata/TimePartition.java       |   2 -
 .../apache/lens/cube/metadata/UpdatePeriod.java |  57 ++++++--
 .../timeline/StoreAllPartitionTimeline.java     |   5 +-
 .../org/apache/lens/cube/parse/DateUtil.java    |  77 ++++------
 .../org/apache/lens/cube/parse/TimeRange.java   |   2 +-
 .../cube/metadata/TestCubeMetastoreClient.java  |  21 +--
 .../lens/cube/metadata/TestTimePartition.java   |  64 +++++----
 .../lens/cube/metadata/UpdatePeriodTest.java    |  60 ++++++++
 .../timeline/TestPartitionTimelines.java        | 143 +++++++++++--------
 .../apache/lens/cube/parse/TestDateUtil.java    |   4 +-
 10 files changed, 258 insertions(+), 177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
index 11e6ef6..d52f168 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartition.java
@@ -37,8 +37,6 @@ public class TimePartition implements Comparable<TimePartition>, Named {
 
   private TimePartition(@NonNull UpdatePeriod updatePeriod, @NonNull Date date) {
     this.updatePeriod = updatePeriod;
-    Calendar cal = Calendar.getInstance();
-    cal.setTime(date);
     this.date = updatePeriod.truncate(date);
     this.dateString = updatePeriod.format().format(this.date);
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
index b4dff46..6c61e94 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
@@ -27,22 +27,28 @@ import java.util.Calendar;
 import java.util.Comparator;
 import java.util.Date;
 
+import org.apache.lens.cube.error.LensCubeErrorCode;
 import org.apache.lens.cube.parse.DateUtil;
+import org.apache.lens.server.api.error.LensException;
 
 import org.apache.commons.lang3.time.DateUtils;
 
+import lombok.Getter;
+
 public enum UpdatePeriod implements Named {
-  SECONDLY(SECOND, 1000, 1.4f, "yyyy-MM-dd-HH-mm-ss"),
-  MINUTELY(MINUTE, 60 * SECONDLY.weight(), 1.35f, "yyyy-MM-dd-HH-mm"),
-  HOURLY(HOUR_OF_DAY, 60 * MINUTELY.weight(), 1.3f, "yyyy-MM-dd-HH"),
-  DAILY(DAY_OF_MONTH, 24 * HOURLY.weight(), 1f, "yyyy-MM-dd"),
-  WEEKLY(WEEK_OF_YEAR, 7 * DAILY.weight(), 0.7f, "yyyy-'W'ww"),
-  MONTHLY(MONTH, 30 * DAILY.weight(), 0.6f, "yyyy-MM"),
-  QUARTERLY(MONTH, 3 * MONTHLY.weight(), 0.55f, "yyyy-MM"),
-  YEARLY(YEAR, 12 * MONTHLY.weight(), 0.52f, "yyyy"),
-  CONTINUOUS(Calendar.SECOND, 1, 1.5f, "yyyy-MM-dd-HH-mm-ss");
+  SECONDLY("second", SECOND, 1000, 1.4f, "yyyy-MM-dd-HH-mm-ss"),
+  MINUTELY("minute", MINUTE, 60 * SECONDLY.weight(), 1.35f, "yyyy-MM-dd-HH-mm"),
+  HOURLY("hour", HOUR_OF_DAY, 60 * MINUTELY.weight(), 1.3f, "yyyy-MM-dd-HH"),
+  DAILY("day", DAY_OF_MONTH, 24 * HOURLY.weight(), 1f, "yyyy-MM-dd"),
+  WEEKLY("week", WEEK_OF_YEAR, 7 * DAILY.weight(), 0.7f, "YYYY-'W'ww"),
+  MONTHLY("month", MONTH, 30 * DAILY.weight(), 0.6f, "yyyy-MM"),
+  QUARTERLY("quarter", MONTH, 3 * MONTHLY.weight(), 0.55f, "yyyy-MM"),
+  YEARLY("year", YEAR, 12 * MONTHLY.weight(), 0.52f, "yyyy"),
+  CONTINUOUS("continuous", Calendar.SECOND, 1, 1.5f, "yyyy-MM-dd-HH-mm-ss");
 
   public static final long MIN_INTERVAL = values()[0].weight();
+  @Getter
+  private String unitName;
   private final int calendarField;
   private final long weight;
   /**
@@ -159,7 +165,8 @@ public enum UpdatePeriod implements Named {
   private static ThreadLocal<DateFormat> quarterlyFormat;
   private static ThreadLocal<DateFormat> yearlyFormat;
 
-  UpdatePeriod(int calendarField, long diff, float normalizationFactor, String format) {
+  UpdatePeriod(String unitName, int calendarField, long diff, float normalizationFactor, String format) {
+    this.unitName = unitName;
     this.calendarField = calendarField;
     this.weight = diff;
     this.normalizationFactor = normalizationFactor;
@@ -178,6 +185,15 @@ public enum UpdatePeriod implements Named {
     return DateUtil.getNumberofDaysInMonth(date) * DAILY.weight();
   }
 
+  public static UpdatePeriod fromUnitName(String unitName) throws LensException {
+    for (UpdatePeriod up : values()) {
+      if (up.getUnitName().equals(unitName)) {
+        return up;
+      }
+    }
+    throw new LensException(LensCubeErrorCode.INVALID_TIME_UNIT.getValue(), unitName);
+  }
+
   public DateFormat format() {
     switch (this) {
     case CONTINUOUS:
@@ -221,21 +237,36 @@ public enum UpdatePeriod implements Named {
   }
 
   public Date truncate(Date date) {
-    if (this.equals(UpdatePeriod.WEEKLY)) {
+    switch (this) {
+    case WEEKLY:
       Date truncDate = DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
       Calendar cal = Calendar.getInstance();
       cal.setTime(truncDate);
       cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
       return cal.getTime();
-    } else if (this.equals(UpdatePeriod.QUARTERLY)) {
+    case QUARTERLY:
       Date dt = DateUtils.truncate(date, this.calendarField());
       dt.setMonth(dt.getMonth() - dt.getMonth() % 3);
       return dt;
-    } else {
+    default:
       return DateUtils.truncate(date, this.calendarField());
     }
   }
 
+  public Calendar truncate(Calendar calendar) {
+    Calendar cal = Calendar.getInstance();
+    cal.setTime(truncate(calendar.getTime()));
+    return cal;
+  }
+
+  public void increment(Calendar calendar, int increment) {
+    switch (this) {
+    case QUARTERLY:
+      increment *= 3;
+    }
+    calendar.add(calendarField(), increment);
+  }
+
   public static class UpdatePeriodComparator implements Comparator<UpdatePeriod> {
     @Override
     public int compare(UpdatePeriod o1, UpdatePeriod o2) {

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/StoreAllPartitionTimeline.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/StoreAllPartitionTimeline.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/StoreAllPartitionTimeline.java
index c82da7b..a6cb8da 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/StoreAllPartitionTimeline.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/StoreAllPartitionTimeline.java
@@ -84,11 +84,10 @@ public class StoreAllPartitionTimeline extends PartitionTimeline {
     if (partitionsStr == null) {
       return true;
     }
-    boolean ret = true;
     for (String s : StringUtils.split(partitionsStr, ",")) {
-      ret &= add(TimePartition.of(getUpdatePeriod(), s));
+      add(TimePartition.of(getUpdatePeriod(), s));
     }
-    return ret;
+    return true;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
index 486c6b3..90ea63c 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
@@ -50,7 +50,18 @@ public final class DateUtil {
    * NOW -> new java.util.Date() NOW-7DAY -> a date one week earlier NOW (+-)
    * <NUM>UNIT or Hardcoded dates in DD-MM-YYYY hh:mm:ss,sss
    */
-  public static final String UNIT = "year|month|week|day|hour|minute|second";
+  public static final String UNIT;
+
+  static {
+    StringBuilder sb = new StringBuilder();
+    String sep = "";
+    for (UpdatePeriod up : UpdatePeriod.values()) {
+      sb.append(sep).append(up.getUnitName());
+      sep = "|";
+    }
+    UNIT = sb.toString();
+  }
+
   public static final String GRANULARITY = "\\.(" + UNIT + ")";
   public static final String RELATIVE = "(now){1}(" + GRANULARITY + "){0,1}";
   public static final Pattern P_RELATIVE = Pattern.compile(RELATIVE, Pattern.CASE_INSENSITIVE);
@@ -127,9 +138,11 @@ public final class DateUtil {
       return resolveAbsoluteDate(str);
     }
   }
+
   public static String relativeToAbsolute(String relative) throws LensException {
     return relativeToAbsolute(relative, new Date());
   }
+
   public static String relativeToAbsolute(String relative, Date now) throws LensException {
     if (RELDATE_VALIDATOR.matcher(relative).matches()) {
       return ABSDATE_PARSER.get().format(resolveRelativeDate(relative, now));
@@ -166,24 +179,7 @@ public final class DateUtil {
       Matcher granularityMatcher = P_UNIT.matcher(nowWithGranularity);
       if (granularityMatcher.find()) {
         String unit = granularityMatcher.group().toLowerCase();
-        if ("year".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, YEAR);
-        } else if ("month".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, MONTH);
-        } else if ("week".equals(unit)) {
-          calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
-          calendar = DateUtils.truncate(calendar, DAY_OF_MONTH);
-        } else if ("day".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, DAY_OF_MONTH);
-        } else if ("hour".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, Calendar.HOUR_OF_DAY);
-        } else if ("minute".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, Calendar.MINUTE);
-        } else if ("second".equals(unit)) {
-          calendar = DateUtils.truncate(calendar, Calendar.SECOND);
-        } else {
-          throw new LensException(LensCubeErrorCode.INVALID_TIME_UNIT.getValue(), unit);
-        }
+        calendar = UpdatePeriod.fromUnitName(granularityMatcher.group().toLowerCase()).truncate(calendar);
       }
     }
 
@@ -386,11 +382,9 @@ public final class DateUtil {
     case CONTINUOUS:
       return getMilliSecondCoveringInfo(from, to, 1000);
     case MINUTELY:
-      return getMilliSecondCoveringInfo(from, to, 1000 * 60);
     case HOURLY:
-      return getMilliSecondCoveringInfo(from, to, 1000 * 60 * 60);
     case DAILY:
-      return getMilliSecondCoveringInfo(from, to, 1000 * 60 * 60 * 24);
+      return getMilliSecondCoveringInfo(from, to, interval.weight());
     case WEEKLY:
       return getWeeklyCoveringInfo(from, to);
     case MONTHLY:
@@ -404,7 +398,7 @@ public final class DateUtil {
     }
   }
 
-  private static CoveringInfo getMilliSecondCoveringInfo(Date from, Date to, int millisInInterval) {
+  private static CoveringInfo getMilliSecondCoveringInfo(Date from, Date to, long millisInInterval) {
     long diff = to.getTime() - from.getTime();
     return new CoveringInfo((int) (diff / millisInInterval), diff % millisInInterval == 0);
   }
@@ -419,7 +413,11 @@ public final class DateUtil {
   }
 
   public static int getTimeDiff(Date fromDate, Date toDate, UpdatePeriod updatePeriod) {
-    return getCoveringInfo(fromDate, toDate, updatePeriod).getCountBetween();
+    if (fromDate.before(toDate)) {
+      return getCoveringInfo(fromDate, toDate, updatePeriod).getCountBetween();
+    } else {
+      return -getCoveringInfo(toDate, fromDate, updatePeriod).getCountBetween();
+    }
   }
 
   @Data
@@ -436,11 +434,11 @@ public final class DateUtil {
   @EqualsAndHashCode
   static class TimeDiff {
     int quantity;
-    int calendarField;
+    UpdatePeriod updatePeriod;
 
-    public TimeDiff(int quantity, int calendarField) {
+    private TimeDiff(int quantity, UpdatePeriod updatePeriod) {
       this.quantity = quantity;
-      this.calendarField = calendarField;
+      this.updatePeriod = updatePeriod;
     }
 
     static TimeDiff parseFrom(String diffStr) throws LensException {
@@ -461,34 +459,17 @@ public final class DateUtil {
 
       Matcher unitMatcher = P_UNIT.matcher(diffStr);
       if (unitMatcher.find()) {
-        String unit = unitMatcher.group().toLowerCase();
-        if ("year".equals(unit)) {
-          return new TimeDiff(qty, YEAR);
-        } else if ("month".equals(unit)) {
-          return new TimeDiff(qty, MONTH);
-        } else if ("week".equals(unit)) {
-          return new TimeDiff(7 * qty, DAY_OF_MONTH);
-        } else if ("day".equals(unit)) {
-          return new TimeDiff(qty, DAY_OF_MONTH);
-        } else if ("hour".equals(unit)) {
-          return new TimeDiff(qty, HOUR_OF_DAY);
-        } else if ("minute".equals(unit)) {
-          return new TimeDiff(qty, MINUTE);
-        } else if ("second".equals(unit)) {
-          return new TimeDiff(qty, SECOND);
-        } else {
-          throw new LensException(LensCubeErrorCode.INVALID_TIME_UNIT.getValue(), unit);
-        }
+        return new TimeDiff(qty, UpdatePeriod.fromUnitName(unitMatcher.group().toLowerCase()));
       }
-      return new TimeDiff(0, SECOND);
+      return new TimeDiff(0, UpdatePeriod.CONTINUOUS);
     }
 
     public Date offsetFrom(Date time) {
-      return DateUtils.add(time, calendarField, quantity);
+      return DateUtils.add(time, updatePeriod.calendarField(), quantity);
     }
 
     public Date negativeOffsetFrom(Date time) {
-      return DateUtils.add(time, calendarField, -quantity);
+      return DateUtils.add(time, updatePeriod.calendarField(), -quantity);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
index 5444e71..b02499e 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
@@ -197,7 +197,7 @@ public class TimeRange {
       @Override
       public Date next() {
         Date cur = calendar.getTime();
-        calendar.add(updatePeriod.calendarField(), increment);
+        updatePeriod.increment(calendar, increment);
         counter++;
         return cur;
       }

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
index c2980af..7d5ed0f 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestCubeMetastoreClient.java
@@ -28,6 +28,7 @@ import org.apache.lens.cube.metadata.ReferencedDimAtrribute.ChainRefCol;
 import org.apache.lens.cube.metadata.timeline.EndsAndHolesPartitionTimeline;
 import org.apache.lens.cube.metadata.timeline.PartitionTimeline;
 import org.apache.lens.cube.metadata.timeline.StoreAllPartitionTimeline;
+import org.apache.lens.cube.metadata.timeline.TestPartitionTimelines;
 import org.apache.lens.cube.parse.TimeRange;
 import org.apache.lens.server.api.error.LensException;
 
@@ -1447,26 +1448,12 @@ public class TestCubeMetastoreClient {
   private void assertSameTimelines(String factName, String[] storages, UpdatePeriod updatePeriod, String[] partCols)
     throws HiveException, LensException {
     for (String partCol : partCols) {
-      PartitionTimeline[] timelines = new PartitionTimeline[storages.length];
+      ArrayList<PartitionTimeline> timelines = Lists.newArrayList();
       for (int i = 0; i < storages.length; i++) {
-        timelines[i] = client.partitionTimelineCache.get(factName, storages[i], updatePeriod, partCol);
+        timelines.add(client.partitionTimelineCache.get(factName, storages[i], updatePeriod, partCol));
       }
-      for (int i = 0; i < timelines.length; i++) {
-        for (int j = i + 1; j < timelines.length; j++) {
-          assertSameTimelines(timelines[i], timelines[j]);
-        }
-      }
-    }
-  }
-
-  private void assertSameTimelines(PartitionTimeline timeline1, PartitionTimeline timeline2) {
-    Iterator<TimePartition> iter1 = timeline1.iterator();
-    Iterator<TimePartition> iter2 = timeline2.iterator();
-    while (iter1.hasNext()) {
-      Assert.assertTrue(iter2.hasNext());
-      assertEquals(iter1.next(), iter2.next());
+      TestPartitionTimelines.assertSameTimelines(timelines);
     }
-    Assert.assertFalse(iter2.hasNext());
   }
 
   private StoragePartitionDesc getStoragePartSpec(String cubeFactName, UpdatePeriod updatePeriod,

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestTimePartition.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestTimePartition.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestTimePartition.java
index 334ea4f..2cbbd0c 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestTimePartition.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/TestTimePartition.java
@@ -25,44 +25,46 @@ import java.util.Date;
 
 import org.apache.lens.server.api.error.LensException;
 
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 public class TestTimePartition {
   public static final Date NOW = new Date();
 
-  @Test
-  public void test() throws LensException {
-    // Test for all update periods
-    for (UpdatePeriod up : UpdatePeriod.values()) {
-      // Normal date object parsable
-      String nowStr = up.format().format(NOW);
+  @DataProvider(name = "update-periods")
+  public Object[][] provideUpdatePeriods() {
+    return UpdatePeriodTest.provideUpdatePeriods();
+  }
 
-      // Create partition by date object or it's string representation -- both should be same.
-      TimePartition nowPartition = TimePartition.of(up, NOW);
-      TimePartition nowStrPartition = TimePartition.of(up, nowStr);
-      assertEquals(nowPartition, nowStrPartition);
-
-      // Test next and previous
-      assertTrue(nowPartition.next().after(nowPartition));
-      assertTrue(nowPartition.previous().before(nowPartition));
-
-      // date parse failures should give lens exception
-      assertEquals(getLensExceptionFromPartitionParsing(up, "garbage").getMessage(),
-        TimePartition.getWrongUpdatePeriodMessage(up, "garbage"));
-      getLensExceptionFromPartitionParsing(up, (Date) null);
-      getLensExceptionFromPartitionParsing(up, (String) null);
-      getLensExceptionFromPartitionParsing(up, "");
-
-      // parse with other update periods
-      for (UpdatePeriod up2 : UpdatePeriod.values()) {
-        // handles the equality case and the case where monthly-quarterly have same format strings.
-        if (up.formatStr().equals(up2.formatStr())) {
-          continue;
-        }
-        // Parsing a string representation with differnet update period should give lens exception.
-        assertEquals(getLensExceptionFromPartitionParsing(up2, nowStr).getMessage(),
-          TimePartition.getWrongUpdatePeriodMessage(up2, nowStr));
+  @Test(dataProvider = "update-periods")
+  public void test(UpdatePeriod up) throws LensException {
+    // Normal date object parsable
+    String nowStr = up.format().format(NOW);
+    // Create partition by date object or it's string representation -- both should be same.
+    TimePartition nowPartition = TimePartition.of(up, NOW);
+    TimePartition nowStrPartition = TimePartition.of(up, nowStr);
+    assertEquals(nowPartition, nowStrPartition);
+
+    // Test next and previous
+    assertTrue(nowPartition.next().after(nowPartition));
+    assertTrue(nowPartition.previous().before(nowPartition));
+
+    // date parse failures should give lens exception
+    assertEquals(getLensExceptionFromPartitionParsing(up, "garbage").getMessage(),
+      TimePartition.getWrongUpdatePeriodMessage(up, "garbage"));
+    getLensExceptionFromPartitionParsing(up, (Date) null);
+    getLensExceptionFromPartitionParsing(up, (String) null);
+    getLensExceptionFromPartitionParsing(up, "");
+
+    // parse with other update periods
+    for (UpdatePeriod up2 : UpdatePeriod.values()) {
+      // handles the equality case and the case where monthly-quarterly have same format strings.
+      if (up.formatStr().equals(up2.formatStr())) {
+        continue;
       }
+      // Parsing a string representation with differnet update period should give lens exception.
+      assertEquals(getLensExceptionFromPartitionParsing(up2, nowStr).getMessage(),
+        TimePartition.getWrongUpdatePeriodMessage(up2, nowStr));
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/test/java/org/apache/lens/cube/metadata/UpdatePeriodTest.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/UpdatePeriodTest.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/UpdatePeriodTest.java
new file mode 100644
index 0000000..b21341d
--- /dev/null
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/UpdatePeriodTest.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.lens.cube.metadata;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Date;
+import java.util.Random;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+public class UpdatePeriodTest {
+  public static class RandomDateGenerator {
+    Random random = new Random();
+    long begin = 1377424977000L;
+    long end = 1598349777000L;
+
+    public Date nextDate() {
+      return new Date(begin + (random.nextLong() % (end - begin)));
+    }
+  }
+
+  @DataProvider(name = "update-periods")
+  public static Object[][] provideUpdatePeriods() {
+    UpdatePeriod[] values = UpdatePeriod.values();
+    Object[][] ret = new Object[values.length][1];
+    for (int i = 0; i < values.length; i++) {
+      ret[i][0] = values[i];
+    }
+    return ret;
+  }
+
+  @Test(dataProvider = "update-periods")
+  public void testFormat(UpdatePeriod period) throws Exception {
+    RandomDateGenerator randomDateGenerator = new RandomDateGenerator();
+    for (int i = 0; i < 5000; i++) {
+      Date randomDate = randomDateGenerator.nextDate();
+      randomDate = period.truncate(randomDate);
+      assertEquals(randomDate, period.format().parse(period.format().format(randomDate)));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/test/java/org/apache/lens/cube/metadata/timeline/TestPartitionTimelines.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/timeline/TestPartitionTimelines.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/timeline/TestPartitionTimelines.java
index 0268bbf..3f9e125 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/metadata/timeline/TestPartitionTimelines.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/timeline/TestPartitionTimelines.java
@@ -18,25 +18,28 @@
  */
 package org.apache.lens.cube.metadata.timeline;
 
+import static org.testng.Assert.*;
+
+import java.lang.reflect.InvocationTargetException;
 import java.util.*;
 
 import org.apache.lens.cube.metadata.TestTimePartition;
 import org.apache.lens.cube.metadata.TimePartition;
 import org.apache.lens.cube.metadata.UpdatePeriod;
+import org.apache.lens.cube.metadata.UpdatePeriodTest;
 import org.apache.lens.server.api.error.LensException;
 
-import org.testng.Assert;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-import com.beust.jcommander.internal.Lists;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
 public class TestPartitionTimelines {
 
   private static final String TABLE_NAME = "storage_fact";
-  public static final UpdatePeriod PERIOD = UpdatePeriod.HOURLY;
   private static final String PART_COL = "pt";
   private static final List<Class<? extends PartitionTimeline>> TIMELINE_IMPLEMENTATIONS = Arrays.asList(
     StoreAllPartitionTimeline.class,
@@ -44,46 +47,48 @@ public class TestPartitionTimelines {
     RangesPartitionTimeline.class
   );
 
-  @Test
-  public void testPropertiesContractsForAllSubclasses() throws LensException {
-    for (Class<? extends PartitionTimeline> clazz : TIMELINE_IMPLEMENTATIONS) {
-      testPropertiesContract(clazz);
+  @DataProvider(name = "update-periods")
+  public Object[][] provideUpdatePeriods() {
+    return UpdatePeriodTest.provideUpdatePeriods();
+  }
+
+  @DataProvider(name = "update-periods-and-timeline-classes")
+  public Object[][] provideUpdatePeriodsAndTimelineClasses() {
+    UpdatePeriod[] values = UpdatePeriod.values();
+    Object[][] ret = new Object[values.length * TIMELINE_IMPLEMENTATIONS.size()][2];
+    for (int i = 0; i < values.length; i++) {
+      for (int j = 0; j < TIMELINE_IMPLEMENTATIONS.size(); j++) {
+        ret[TIMELINE_IMPLEMENTATIONS.size() * i + j] = new Object[]{
+          values[i],
+          TIMELINE_IMPLEMENTATIONS.get(j),
+        };
+      }
     }
+    return ret;
   }
 
-  @Test
-  public void testEquivalence() throws LensException {
+
+  @Test(dataProvider = "update-periods")
+  public void testEquivalence(UpdatePeriod period) throws LensException, InvocationTargetException,
+    NoSuchMethodException, InstantiationException, IllegalAccessException {
+    final Random randomGenerator = new Random();
     for (int j = 0; j < 10; j++) {
-      Random randomGenerator = new Random();
       List<PartitionTimeline> timelines = Lists.newArrayList();
       for (Class<? extends PartitionTimeline> clazz : TIMELINE_IMPLEMENTATIONS) {
-        timelines.add(getInstance(clazz));
+        timelines.add(getInstance(clazz, period));
       }
       final List<TimePartition> addedPartitions = Lists.newArrayList();
-      for (int i = 0; i < 200; i++) {
-        int randomInt = randomGenerator.nextInt(100) - 50;
-        TimePartition part = TimePartition.of(PERIOD, TestTimePartition.timeAtDiff(TestTimePartition.NOW, PERIOD,
+      for (int i = 0; i < 20; i++) {
+        int randomInt = randomGenerator.nextInt(10) - 5;
+        TimePartition part = TimePartition.of(period, TestTimePartition.timeAtDiff(TestTimePartition.NOW, period,
           randomInt));
         addedPartitions.add(part);
         for (PartitionTimeline timeline : timelines) {
           timeline.add(part);
         }
+        assertSameTimelines(timelines);
       }
-      Iterator<TimePartition> sourceOfTruth = timelines.get(0).iterator();
-      List<Iterator<TimePartition>> otherIterators = Lists.newArrayList();
-      for (int i = 1; i < TIMELINE_IMPLEMENTATIONS.size() - 1; i++) {
-        otherIterators.add(timelines.get(i).iterator());
-      }
-      while (sourceOfTruth.hasNext()) {
-        TimePartition cur = sourceOfTruth.next();
-        for (Iterator<TimePartition> iterator : otherIterators) {
-          Assert.assertTrue(iterator.hasNext());
-          Assert.assertEquals(iterator.next(), cur);
-        }
-      }
-      for (Iterator<TimePartition> iterator : otherIterators) {
-        Assert.assertFalse(iterator.hasNext());
-      }
+      assertSameTimelines(timelines);
       Collections.shuffle(addedPartitions);
       Iterator<TimePartition> iter = addedPartitions.iterator();
       while (iter.hasNext()) {
@@ -92,62 +97,80 @@ public class TestPartitionTimelines {
         if (!addedPartitions.contains(part)) {
           for (PartitionTimeline timeline : timelines) {
             timeline.drop(part);
+            assertTrue(timeline.isConsistent());
           }
         }
       }
       for (PartitionTimeline timeline : timelines) {
-        Assert.assertTrue(timeline.isEmpty());
+        assertTrue(timeline.isEmpty());
       }
     }
   }
 
+  public static void assertSameTimelines(List<PartitionTimeline> timelines) {
+    List<Iterator<TimePartition>> iterators = Lists.newArrayList();
+    for (PartitionTimeline timeline : timelines) {
+      iterators.add(timeline.iterator());
+    }
 
-  private <T extends PartitionTimeline> T getInstance(Class<T> clz) {
-    try {
-      return clz.getConstructor(String.class, UpdatePeriod.class, String.class)
-        .newInstance(TABLE_NAME, PERIOD, PART_COL);
-    } catch (Exception e) {
-      log.error("Error while getting instance.", e);
+    while (iterators.get(0).hasNext()) {
+      Map<Class, TimePartition> parts = Maps.newHashMap();
+      for (Iterator<TimePartition> iterator : iterators) {
+        assertTrue(iterator.hasNext());
+        parts.put(iterator.getClass(), iterator.next());
+      }
+      assertEquals(new HashSet<>(parts.values()).size(), 1, "More than one values for next: " + parts.values());
     }
-    return null;
+    for (Iterator<TimePartition> iterator : iterators) {
+      assertFalse(iterator.hasNext());
+    }
+  }
+
+
+  private <T extends PartitionTimeline> T getInstance(Class<T> clz, UpdatePeriod period) throws
+    NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+    return clz.getConstructor(String.class, UpdatePeriod.class, String.class)
+      .newInstance(TABLE_NAME, period, PART_COL);
   }
 
-  private <T extends PartitionTimeline> void testPropertiesContract(Class<T> clz) throws LensException {
+  @Test(dataProvider = "update-periods-and-timeline-classes")
+  public <T extends PartitionTimeline> void testPropertiesContract(UpdatePeriod period, Class<T> clz) throws
+    LensException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
     // Make two instances, one to modify, other to validate against
-    T inst1 = getInstance(clz);
-    T inst2 = getInstance(clz);
+    T inst1 = getInstance(clz, period);
+    T inst2 = getInstance(clz, period);
     // whenever we'll init from props, timeline should become empty.
     Map<String, String> props = inst1.toProperties();
-    Assert.assertTrue(inst2.initFromProperties(props));
+    assertTrue(inst2.initFromProperties(props));
     // init from props of an empty timeline: should succeed and make the timeline empty
-    Assert.assertEquals(inst1, inst2);
-    Assert.assertTrue(inst1.isEmpty());
-    Assert.assertTrue(inst2.isEmpty());
+    assertEquals(inst1, inst2);
+    assertTrue(inst1.isEmpty());
+    assertTrue(inst2.isEmpty());
     // Add single partition and test for non-equivalence
-    Assert.assertTrue(inst1.add(TimePartition.of(PERIOD, TestTimePartition.NOW)));
-    Assert.assertFalse(inst1.equals(inst2));
+    assertTrue(inst1.add(TimePartition.of(period, TestTimePartition.NOW)));
+    assertFalse(inst1.equals(inst2));
     // add same parittion in other timeline, test for equality
-    Assert.assertTrue(inst2.add(TimePartition.of(PERIOD, TestTimePartition.NOW)));
-    Assert.assertTrue(inst1.isConsistent());
-    Assert.assertTrue(inst2.isConsistent());
-    Assert.assertEquals(inst1, inst2);
+    assertTrue(inst2.add(TimePartition.of(period, TestTimePartition.NOW)));
+    assertTrue(inst1.isConsistent());
+    assertTrue(inst2.isConsistent());
+    assertEquals(inst1, inst2);
     // init with blank properties. Should become empty
-    Assert.assertTrue(inst2.initFromProperties(props));
-    Assert.assertFalse(inst1.equals(inst2));
+    assertTrue(inst2.initFromProperties(props));
+    assertFalse(inst1.equals(inst2));
     // init from properties of timeline with single partition.
-    Assert.assertTrue(inst2.initFromProperties(inst1.toProperties()));
-    Assert.assertEquals(inst1, inst2);
+    assertTrue(inst2.initFromProperties(inst1.toProperties()));
+    assertEquals(inst1, inst2);
     // clear timelines
     inst1.initFromProperties(props);
     inst2.initFromProperties(props);
     // Make sparse partition range in one, init other from its properties. Test equality.
-    for (int i = 0; i < 5000; i++) {
-      Assert.assertTrue(inst1.add(TimePartition.of(PERIOD, TestTimePartition.timeAtDiff(TestTimePartition.NOW, PERIOD,
+    for (int i = 0; i < 500; i++) {
+      assertTrue(inst1.add(TimePartition.of(period, TestTimePartition.timeAtDiff(TestTimePartition.NOW, period,
         i * 2))));
     }
-    Assert.assertTrue(inst1.isConsistent());
+    assertTrue(inst1.isConsistent());
     inst2.initFromProperties(inst1.toProperties());
-    Assert.assertTrue(inst2.isConsistent());
-    Assert.assertEquals(inst1, inst2);
+    assertTrue(inst2.isConsistent());
+    assertEquals(inst1, inst2);
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/86f251a7/lens-cube/src/test/java/org/apache/lens/cube/parse/TestDateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestDateUtil.java b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestDateUtil.java
index 89d210f..ab88fbe 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/parse/TestDateUtil.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/parse/TestDateUtil.java
@@ -262,7 +262,7 @@ public class TestDateUtil {
     assertEquals(diffs.size(), 1);
     TimeDiff minusFourDaysDiff = diffs.iterator().next();
     assertEquals(minusFourDaysDiff.quantity, -4);
-    assertEquals(minusFourDaysDiff.calendarField, DAY_OF_MONTH);
+    assertEquals(minusFourDaysDiff.updatePeriod, DAILY);
 
     diffs.clear();
     for (String diffStr : plusFourDays) {
@@ -271,7 +271,7 @@ public class TestDateUtil {
     assertEquals(diffs.size(), 1);
     TimeDiff plusFourDaysDiff = diffs.iterator().next();
     assertEquals(plusFourDaysDiff.quantity, 4);
-    assertEquals(plusFourDaysDiff.calendarField, DAY_OF_MONTH);
+    assertEquals(plusFourDaysDiff.updatePeriod, DAILY);
     Date now = new Date();
     assertEquals(minusFourDaysDiff.offsetFrom(plusFourDaysDiff.offsetFrom(now)), now);
     assertEquals(plusFourDaysDiff.offsetFrom(minusFourDaysDiff.offsetFrom(now)), now);


[12/50] [abbrv] lens git commit: Revert "LENS-737 : Throw single error out with LensMultiException"

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
index ac1c558..603d7cb 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensException.java
@@ -31,9 +31,7 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.error.LensError;
 import org.apache.lens.api.result.LensAPIResult;
 import org.apache.lens.api.result.LensErrorTO;
-import org.apache.lens.server.api.LensErrorInfo;
 
-import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
 
 import lombok.Getter;
@@ -43,27 +41,13 @@ import lombok.NonNull;
  * The Class LensException.
  */
 @SuppressWarnings("serial")
-public class LensException extends Exception implements Comparable<LensException> {
+public class LensException extends Exception {
 
   private static final int DEFAULT_LENS_EXCEPTION_ERROR_CODE = INTERNAL_SERVER_ERROR.getValue();
-  private static final int DEFAULT_LENS_EXCEPTION_WEIGHT = 0;
-
-  private static  LensErrorInfo defaultErrorInfo =
-      new LensErrorInfo(DEFAULT_LENS_EXCEPTION_ERROR_CODE, DEFAULT_LENS_EXCEPTION_WEIGHT, INTERNAL_SERVER_ERROR.name());
-
-  private Object[] errorMsgFormattingArgs = new Object[0];
 
   @Getter
-  private final LensErrorInfo errorInfo;
-
-  public int getErrorCode() {
-    return errorInfo.getErrorCode();
-  }
-
-  public int getErrorWeight() {
-    return errorInfo.getErrorWeight();
-  }
-
+  private final int errorCode;
+  private Object[] errorMsgFormattingArgs = new Object[0];
 
   /**
    * The lensResponse prepared by {@link #buildLensErrorResponse(ErrorCollection, String, String)}
@@ -77,7 +61,7 @@ public class LensException extends Exception implements Comparable<LensException
    * @see Exception#Exception(String)
    */
   public LensException(String errorMsg) {
-    this(errorMsg, defaultErrorInfo);
+    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
   }
 
   /**
@@ -86,7 +70,7 @@ public class LensException extends Exception implements Comparable<LensException
    * @see Exception#Exception(String, Throwable)
    */
   public LensException(String errorMsg, Throwable cause) {
-    this(errorMsg, defaultErrorInfo, cause);
+    this(errorMsg, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
   }
 
   /**
@@ -95,7 +79,7 @@ public class LensException extends Exception implements Comparable<LensException
    * @see Exception#Exception()
    */
   public LensException() {
-    this(null, defaultErrorInfo);
+    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE);
   }
 
   /**
@@ -104,100 +88,79 @@ public class LensException extends Exception implements Comparable<LensException
    * @see Exception#Exception(Throwable)
    */
   public LensException(Throwable cause) {
-    this(defaultErrorInfo, cause);
+    this(null, DEFAULT_LENS_EXCEPTION_ERROR_CODE, cause);
   }
 
   /**
-   * Constructs a new Lens Exception with error info.
+   * Constructs a new Lens Exception with error code.
    *
    * @see Exception#Exception()
    */
-  public LensException(final LensErrorInfo errorInfo) {
-    this(null, errorInfo);
+  public LensException(final int errorCode) {
+    this(null, errorCode);
   }
 
   /**
-   * Constructs a new Lens Exception with error msg and error info.
+   * Constructs a new Lens Exception with error msg and error code.
    *
    * @see Exception#Exception()
    */
-  public LensException(final String errorMsg, final LensErrorInfo errorInfo) {
-    this(errorMsg, errorInfo, null);
+  public LensException(final String errorMsg, final int errorCode) {
+    this(errorMsg, errorCode, null);
   }
 
   /**
-   * Constructs a new Lens Exception with error info, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with error code, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final LensErrorInfo errorInfo, final Throwable cause,
-      @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorInfo, cause, errorMsgFormattingArgs);
+  public LensException(final int errorCode, final Throwable cause, @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorCode, cause, errorMsgFormattingArgs);
   }
 
   /**
-   * Constructs a new Lens Exception with error info and error msg formatting arguments.
+   * Constructs a new Lens Exception with error code and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final LensErrorInfo errorInfo, @NonNull final Object... errorMsgFormattingArgs) {
-    this(null, errorInfo, null, errorMsgFormattingArgs);
+  public LensException(final int errorCode, @NonNull final Object... errorMsgFormattingArgs) {
+    this(null, errorCode, null, errorMsgFormattingArgs);
   }
 
+
   /**
-   * Constructs a new Lens Exception with exception error message, error info, cause and error msg formatting arguments.
+   * Constructs a new Lens Exception with exception error message, error code, cause and error msg formatting arguments.
    *
    * @see Exception#Exception(Throwable)
    */
-  public LensException(final String errorMsg, final LensErrorInfo errorInfo, final Throwable cause,
+  public LensException(final String errorMsg, final int errorcode, final Throwable cause,
     @NonNull final Object... errorMsgFormattingArgs) {
 
-    super(getErrorMessage(errorMsg, errorInfo, errorMsgFormattingArgs), cause);
-    checkArgument(errorInfo.getErrorCode() > 0);
+    super(errorMsg, cause);
+    checkArgument(errorcode > 0);
 
-    this.errorInfo =  errorInfo;
+    this.errorCode = errorcode;
     this.errorMsgFormattingArgs = errorMsgFormattingArgs;
   }
 
-  private static String getErrorMessage(final String errorMsg, final LensErrorInfo errorInfo,
-      @NonNull final Object... errorMsgFormattingArgs) {
-
-    if (StringUtils.isBlank(errorMsg)) {
-      StringBuilder error = new StringBuilder(errorInfo.getErrorName());
-      if (errorMsgFormattingArgs != null && errorMsgFormattingArgs.length != 0) {
-        error.append(Arrays.asList(errorMsgFormattingArgs));
-      }
-      return error.toString();
-    }
-    return errorMsg;
-  }
-
-  /**
-   * Copy Constructor
-   * @param e
-   */
-  public LensException(LensException e) {
-    this(e.getMessage(), e.getErrorInfo(), e.getCause(), e.errorMsgFormattingArgs);
-  }
-
   public final void buildLensErrorResponse(final ErrorCollection errorCollection,
     final String apiVersion, final String id) {
 
-    final LensError lensError = errorCollection.getLensError(getErrorCode());
+    final LensError lensError = errorCollection.getLensError(errorCode);
     final LensErrorTO lensErrorTO = buildLensErrorTO(errorCollection, lensError);
     lensAPIResult = LensAPIResult.composedOf(apiVersion, id, lensErrorTO, lensError.getHttpStatusCode());
   }
 
   public final LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection) {
 
-    final LensError lensError = errorCollection.getLensError(getErrorCode());
+    final LensError lensError = errorCollection.getLensError(errorCode);
     return buildLensErrorTO(errorCollection, lensError);
   }
 
   protected LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final String errorMsg,
     final String stackTrace) {
 
-    return LensErrorTO.composedOf(getErrorCode(), errorMsg, stackTrace);
+    return LensErrorTO.composedOf(errorCode, errorMsg, stackTrace);
   }
 
   private LensErrorTO buildLensErrorTO(final ErrorCollection errorCollection, final LensError lensError) {
@@ -219,7 +182,7 @@ public class LensException extends Exception implements Comparable<LensException
     }
 
     LensException e = (LensException) o;
-    if (errorInfo.equals(e.errorInfo) && isErrorMsgEqual(e)
+    if (errorCode == e.errorCode && isErrorMsgEqual(e)
       && Arrays.deepEquals(errorMsgFormattingArgs, e.errorMsgFormattingArgs)) {
       return true;
     }
@@ -253,7 +216,7 @@ public class LensException extends Exception implements Comparable<LensException
     final int PRIME = 59;
     int result = 1;
 
-    result = result * PRIME + errorInfo.hashCode();
+    result = result * PRIME + errorCode;
     result = result * PRIME + (this.getMessage() == null ? 0 : this.getMessage().hashCode());
     result = result * PRIME + Arrays.deepHashCode(errorMsgFormattingArgs);
     return result;
@@ -265,9 +228,4 @@ public class LensException extends Exception implements Comparable<LensException
     }
     return new LensException(e);
   }
-
-  @Override
-  public int compareTo(LensException e) {
-    return this.getErrorWeight() - e.getErrorWeight();
-  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
index 5248489..af9e33a 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/error/LensMultiCauseException.java
@@ -18,7 +18,10 @@
  */
 package org.apache.lens.server.api.error;
 
-import java.util.Collections;
+import static org.apache.lens.api.error.LensCommonErrorCode.INTERNAL_SERVER_ERROR;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -26,7 +29,6 @@ import org.apache.lens.api.error.ErrorCollection;
 import org.apache.lens.api.result.LensErrorTO;
 
 import com.google.common.collect.ImmutableList;
-
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.NonNull;
@@ -48,14 +50,14 @@ public class LensMultiCauseException extends LensException {
   @Getter(AccessLevel.PROTECTED)
   private final ImmutableList<LensException> causes;
 
-  public LensMultiCauseException(@NonNull final ImmutableList<LensException> excpList) {
-    super(getAppropriateError(excpList));
-    this.causes = excpList;
-  }
+  public LensMultiCauseException(final String errMsg, @NonNull
+    final ImmutableList<LensException> causes) {
+
+    super(errMsg, INTERNAL_SERVER_ERROR.getValue());
+    checkArgument(causes.size() >= 2, "LensMultiCauseException should only be created when there are atleast "
+        + "two causes. An instance of LensException should be sufficient if there is only one cause.");
 
-  // Get appropriate error code
-  public static LensException getAppropriateError(final ImmutableList<LensException> excpList) {
-    return Collections.max(excpList);
+    this.causes = causes;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
index dc20f0f..917eba3 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/LensServerErrorCode.java
@@ -18,22 +18,20 @@
  */
 package org.apache.lens.server.error;
 
-import org.apache.lens.server.api.LensErrorInfo;
-
 public enum LensServerErrorCode {
 
-  SESSION_ID_NOT_PROVIDED(2001, 0),
-  NULL_OR_EMPTY_OR_BLANK_QUERY(2002, 0),
-  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003, 0);
+  SESSION_ID_NOT_PROVIDED(2001),
+  NULL_OR_EMPTY_OR_BLANK_QUERY(2002),
+  UNSUPPORTED_QUERY_SUBMIT_OPERATION(2003);
 
-  public LensErrorInfo getLensErrorInfo() {
-    return this.errorInfo;
+  public int getValue() {
+    return this.errorCode;
   }
 
-  LensServerErrorCode(final int code, final int weight) {
-    this.errorInfo = new LensErrorInfo(code, weight, name());
+  private LensServerErrorCode(final int code) {
+    this.errorCode = code;
   }
 
-  private final LensErrorInfo errorInfo;
+  private final int errorCode;
 
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
index d90f8fd..366b306 100644
--- a/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
+++ b/lens-server/src/main/java/org/apache/lens/server/error/UnSupportedQuerySubmitOpException.java
@@ -31,11 +31,11 @@ public class UnSupportedQuerySubmitOpException extends LensException {
   private final SupportedQuerySubmitOperations supportedOps = new SupportedQuerySubmitOperations();
 
   public UnSupportedQuerySubmitOpException() {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo());
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue());
   }
 
   public UnSupportedQuerySubmitOpException(final Throwable cause) {
-    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo(), cause);
+    super(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(), cause);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
index 23cc748..c29a1ac 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryExecutionServiceImpl.java
@@ -1275,7 +1275,7 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
           final LensException firstCause = causes.get(0);
           for (LensException cause : causes) {
             if (!cause.equals(firstCause)) {
-              throw new LensMultiCauseException(ImmutableList.copyOf(causes));
+              throw new LensMultiCauseException(StringUtils.join(failureCauses, '\n'), ImmutableList.copyOf(causes));
             }
           }
           throw firstCause;
@@ -1555,11 +1555,15 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
       if (prepared != null) {
         destroyPreparedQuery(prepared);
       }
-      throw e;
-    } catch (UnsupportedEncodingException e) {
-      if (prepared != null) {
-        destroyPreparedQuery(prepared);
+      log.error("Explain and prepare failed", e);
+      QueryPlan plan;
+      if (e.getCause() != null && e.getCause().getMessage() != null) {
+        plan = new QueryPlan(true, e.getCause().getMessage());
+      } else {
+        plan = new QueryPlan(true, e.getMessage());
       }
+      return plan;
+    } catch (UnsupportedEncodingException e) {
       throw new LensException(e);
     } finally {
       release(sessionHandle);
@@ -2255,16 +2259,25 @@ public class QueryExecutionServiceImpl extends BaseLensService implements QueryE
   public QueryPlan explain(final String requestId, LensSessionHandle sessionHandle, String query, LensConf lensConf)
     throws LensException {
     try {
-      log.info("Explain: session:{} query:{}", sessionHandle, query);
+      log.info("Explain: session:{} query:{}",  sessionHandle, query);
       acquire(sessionHandle);
       Configuration qconf = getLensConf(sessionHandle, lensConf);
-      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query, getSession(sessionHandle)
-          .getLoggedInUser(), lensConf, qconf, drivers.values());
+      ExplainQueryContext explainQueryContext = new ExplainQueryContext(requestId, query,
+        getSession(sessionHandle).getLoggedInUser(), lensConf, qconf, drivers.values());
       explainQueryContext.setLensSessionIdentifier(sessionHandle.getPublicId().toString());
       accept(query, qconf, SubmitOp.EXPLAIN);
       rewriteAndSelect(explainQueryContext);
       addSessionResourcesToDriver(explainQueryContext);
       return explainQueryContext.getSelectedDriver().explain(explainQueryContext).toQueryPlan();
+    } catch (LensException e) {
+      log.error("Error during explain :", e);
+      QueryPlan plan;
+      if (e.getCause() != null && e.getCause().getMessage() != null) {
+        plan = new QueryPlan(true, e.getCause().getMessage());
+      } else {
+        plan = new QueryPlan(true, e.getMessage());
+      }
+      return plan;
     } catch (UnsupportedEncodingException e) {
       throw new LensException(e);
     } finally {

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
----------------------------------------------------------------------
diff --git a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
index 96f6aea..6bfd77a 100644
--- a/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
+++ b/lens-server/src/main/java/org/apache/lens/server/query/QueryServiceResource.java
@@ -77,7 +77,7 @@ public class QueryServiceResource {
 
   private void validateSessionId(final LensSessionHandle sessionHandle) throws LensException {
     if (sessionHandle == null) {
-      throw new LensException(SESSION_ID_NOT_PROVIDED.getLensErrorInfo());
+      throw new LensException(SESSION_ID_NOT_PROVIDED.getValue());
     }
   }
 
@@ -104,7 +104,7 @@ public class QueryServiceResource {
 
   private void validateQuery(String query) throws LensException {
     if (StringUtils.isBlank(query)) {
-      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo());
+      throw new LensException(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue());
     }
   }
   /**
@@ -340,24 +340,19 @@ public class QueryServiceResource {
    * @return {@link QueryPrepareHandle} incase of {link org.apache.lens.api.query.SubmitOp#PREPARE} operation.
    *         {@link QueryPlan} incase of {@link org.apache.lens.api.query.SubmitOp#EXPLAIN_AND_PREPARE}
    *         and the query plan will contain the prepare handle as well.
-   * @throws LensException
    */
   @POST
   @Path("preparedqueries")
   @Consumes({MediaType.MULTIPART_FORM_DATA})
   @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
   @MultiPurposeResource(formParamName = "operation")
-  public LensAPIResult<? extends QuerySubmitResult> prepareQuery(
-      @FormDataParam("sessionid") LensSessionHandle sessionid, @FormDataParam("query") String query,
-      @DefaultValue("") @FormDataParam("operation") String operation, @FormDataParam("conf") LensConf conf,
-      @DefaultValue("") @FormDataParam("queryName") String queryName) throws LensException {
-    final String requestId = this.logSegregationContext.getLogSegragationId();
-
+  public QuerySubmitResult prepareQuery(@FormDataParam("sessionid") LensSessionHandle sessionid,
+    @FormDataParam("query") String query, @DefaultValue("") @FormDataParam("operation") String operation,
+    @FormDataParam("conf") LensConf conf, @DefaultValue("") @FormDataParam("queryName") String queryName) {
     try {
       checkSessionId(sessionid);
       checkQuery(query);
       SubmitOp sop = null;
-      QuerySubmitResult result;
       try {
         sop = SubmitOp.valueOf(operation.toUpperCase());
       } catch (IllegalArgumentException e) {
@@ -368,20 +363,17 @@ public class QueryServiceResource {
       }
       switch (sop) {
       case PREPARE:
-        result = queryServer.prepare(sessionid, query, conf, queryName);
-        break;
+        return queryServer.prepare(sessionid, query, conf, queryName);
       case EXPLAIN_AND_PREPARE:
-        result = queryServer.explainAndPrepare(sessionid, query, conf, queryName);
-        break;
+        return queryServer.explainAndPrepare(sessionid, query, conf, queryName);
       default:
         throw new BadRequestException("Invalid operation type: " + operation + prepareClue);
       }
-      return LensAPIResult.composedOf(null, requestId, result);
     } catch (LensException e) {
-      e.buildLensErrorResponse(errorCollection, null, requestId);
-      throw e;
+      throw new WebApplicationException(e);
     }
   }
+
   /**
    * Destroy all the prepared queries; Can be filtered with user.
    *
@@ -398,11 +390,10 @@ public class QueryServiceResource {
    */
   @DELETE
   @Path("preparedqueries")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
+  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
   public APIResult destroyPreparedQueries(@QueryParam("sessionid") LensSessionHandle sessionid,
-      @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
-      @DefaultValue("-1") @QueryParam("fromDate") long fromDate,
-      @DefaultValue("-1") @QueryParam("toDate") long toDate) {
+    @DefaultValue("") @QueryParam("user") String user, @DefaultValue("") @QueryParam("queryName") String queryName,
+    @DefaultValue("-1") @QueryParam("fromDate") long fromDate, @DefaultValue("-1") @QueryParam("toDate") long toDate) {
     checkSessionId(sessionid);
     int numDestroyed = 0;
     boolean failed = false;

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
index 4d4f137..38b5ea0 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/ErrorResponseExpectedData.java
@@ -49,7 +49,7 @@ public class ErrorResponseExpectedData {
 
     /* Assert Equal LensErrorTO (stack trace gets excluded in equality check) */
     final LensErrorTO actualLensErrorTO = lensAPIResult.getLensErrorTO();
-    assertEquals(actualLensErrorTO.getMessage(), expectedLensErrorTO.getMessage());
+    assertEquals(actualLensErrorTO, expectedLensErrorTO);
 
     /* Assert receipt of valid stacktraces */
     assertTrue(lensAPIResult.areValidStackTracesPresent(), "Received Lens Response:" + lensAPIResult);

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
index 2f74ceb..64a75ce 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/FailingQueryDriver.java
@@ -34,7 +34,7 @@ public class FailingQueryDriver extends MockDriver {
     if (ctx.getUserQuery().contains("fail")) {
       return new FactPartitionBasedQueryCost(0.0);
     } else {
-      throw new LensException("Simulated Estimate Failure");
+      throw new LensException();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
index 18a8c8d..2189eb8 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/QueryAPIErrorResponseTest.java
@@ -111,8 +111,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.<LensSessionHandle>absent(), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Session id not provided. Please provide a session id.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-        SESSION_ID_NOT_PROVIDED.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SESSION_ID_NOT_PROVIDED.getValue(), expectedErrMsg,
+      MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -126,8 +126,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), testQuery);
 
     final String expectedErrMsg = "Query is not provided, or it is empty or blank. Please provide a valid query.";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-        NULL_OR_EMPTY_OR_BLANK_QUERY.getLensErrorInfo().getErrorCode(), expectedErrMsg, MOCK_STACK_TRACE);
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(NULL_OR_EMPTY_OR_BLANK_QUERY.getValue(), expectedErrMsg,
+      MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
     expectedData.verify(response);
@@ -144,8 +144,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     final String expectedErrMsg = "Provided Operation is not supported. Supported Operations are: "
       + "[estimate, execute, explain, execute_with_timeout]";
 
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-        UNSUPPORTED_QUERY_SUBMIT_OPERATION.getLensErrorInfo().getErrorCode(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(UNSUPPORTED_QUERY_SUBMIT_OPERATION.getValue(),
       expectedErrMsg, MOCK_STACK_TRACE, new SupportedQuerySubmitOperations());
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -166,9 +165,11 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       expectedErrMsg, MOCK_STACK_TRACE);
     LensErrorTO childError2 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
         expectedErrMsg, MOCK_STACK_TRACE);
+    LensErrorTO childError3 = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
+        expectedErrMsg, MOCK_STACK_TRACE);
 
     LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(INTERNAL_SERVER_ERROR.getValue(),
-        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2));
+        expectedErrMsg, MOCK_STACK_TRACE, Arrays.asList(childError1, childError2, childError3));
 
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(Status.INTERNAL_SERVER_ERROR,
       expectedLensErrorTO);
@@ -184,7 +185,7 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
     Response response = estimate(target(), Optional.of(sessionId), Optional.of(MOCK_QUERY));
 
     final String expectedErrMsg = "Syntax Error: line 1:0 cannot recognize input near 'mock' '-' 'query'";
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getLensErrorInfo().getErrorCode(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(SYNTAX_ERROR.getValue(),
       expectedErrMsg, MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -289,9 +290,8 @@ public class QueryAPIErrorResponseTest extends LensJerseyTest {
       final ColUnAvailableInTimeRange expectedErrorPayload = new ColUnAvailableInTimeRange(testDimensionField,
         expecAvailableFrom, expecAvailableTill);
 
-      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-          COLUMN_UNAVAILABLE_IN_TIME_RANGE.getLensErrorInfo().getErrorCode(),
-          expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
+      LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(COLUMN_UNAVAILABLE_IN_TIME_RANGE.getValue(),
+        expectedErrMsg, MOCK_STACK_TRACE, expectedErrorPayload, null);
       ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
       expectedData.verify(response);

http://git-wip-us.apache.org/repos/asf/lens/blob/fb235faa/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index fa8d6ee..b3f5d93 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -375,7 +375,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+      QueryPlan.class);
     assertEquals(plan2.getTablesQueried().size(), 1);
     assertTrue(plan2.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan2.getPrepareHandle());
@@ -387,41 +387,47 @@ public class TestQueryService extends LensJerseyTest {
    * Test explain failure.
    *
    * @throws InterruptedException the interrupted exception
-   * @throws UnsupportedEncodingException
    */
   @Test
-  public void testExplainFailure() throws InterruptedException, UnsupportedEncodingException {
+  public void testExplainFailure() throws InterruptedException {
     final WebTarget target = target().path("queryapi/queries");
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-        + TEST_TABLE));
+      MediaType.APPLICATION_XML_TYPE));
+    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(),
+      "select NO_ID from " + TEST_TABLE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-        MediaType.APPLICATION_XML_TYPE));
-
-    final Response responseExplain = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
 
-    assertEquals(responseExplain.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    final QueryPlan plan = target.request()
+      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
+        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+    assertTrue(plan.isError());
+    assertNotNull(plan.getErrorMsg());
+    assertTrue(plan.getErrorMsg()
+      .contains("Invalid table alias or column reference 'NO_ID': " + "(possible column names are: id, idstr)"));
 
     // Test explain and prepare
     final WebTarget ptarget = target().path("queryapi/preparedqueries");
 
     final FormDataMultiPart mp2 = new FormDataMultiPart();
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-        + TEST_TABLE));
+      + TEST_TABLE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain_and_prepare"));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-        MediaType.APPLICATION_XML_TYPE));
-
-    final Response responseExplainAndPrepare = target.request().post(
-        Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
 
-    assertEquals(responseExplainAndPrepare.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
+      QueryPlan.class);
+    assertTrue(plan2.isError());
+    assertNotNull(plan2.getErrorMsg());
+    assertNull(plan2.getPrepareHandle());
+    assertTrue(plan2.getErrorMsg().contains("Invalid table alias or column reference 'NO_ID': "
+      + "(possible column names are: id, idstr)"));
   }
 
   // post to preparedqueries
@@ -451,7 +457,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPrepareHandle pHandle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPrepareHandle>>() {}).getData();
+      QueryPrepareHandle.class);
 
     // Get all prepared queries
     List<QueryPrepareHandle> allQueries = (List<QueryPrepareHandle>) target.queryParam("sessionid", lensSessionId)
@@ -549,9 +555,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan = target.request()
-      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-          new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
-
+      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), QueryPlan.class);
     assertEquals(plan.getTablesQueried().size(), 1);
     assertTrue(plan.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan.getPrepareHandle());
@@ -1421,9 +1425,7 @@ public class TestQueryService extends LensJerseyTest {
     final Response response = target.request()
       .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
 
-
-    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-        LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo().getErrorCode(),
+    LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getValue(),
       "Neither cube nor dimensions accessed in the query", TestDataUtils.MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 


[34/50] [abbrv] lens git commit: LENS-772 : Fix time and size based rolling for logs

Posted by ra...@apache.org.
LENS-772 : Fix time and size based rolling for logs


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

Branch: refs/heads/current-release-line
Commit: d524cc24eb93b1ad44c8c148f3d9aabff0740b54
Parents: 7ad12ed
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Wed Sep 23 17:41:41 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Wed Sep 23 17:41:41 2015 +0530

----------------------------------------------------------------------
 tools/conf-pseudo-distr/client/logback.xml | 10 ++++---
 tools/conf-pseudo-distr/server/logback.xml | 37 +++++++++++++------------
 tools/conf/client/logback.xml              | 10 ++++---
 tools/conf/server/logback.xml              | 37 +++++++++++++------------
 4 files changed, 50 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/d524cc24/tools/conf-pseudo-distr/client/logback.xml
----------------------------------------------------------------------
diff --git a/tools/conf-pseudo-distr/client/logback.xml b/tools/conf-pseudo-distr/client/logback.xml
index d142348..8617e17 100644
--- a/tools/conf-pseudo-distr/client/logback.xml
+++ b/tools/conf-pseudo-distr/client/logback.xml
@@ -33,14 +33,16 @@
     </encoder>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensclient.log.%d{yyyy-MM-dd}</fileNamePattern>
+      <fileNamePattern>${lens.log.dir}/lensclient.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
 
+      <timeBasedFileNamingAndTriggeringPolicy
+              class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+        <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <MaxFileSize>100MB</MaxFileSize>
-    </triggeringPolicy>
   </appender>
   <logger name="org.springframework" level="OFF"/>
   <logger name="ch.qos.logback" level="WARN"/>

http://git-wip-us.apache.org/repos/asf/lens/blob/d524cc24/tools/conf-pseudo-distr/server/logback.xml
----------------------------------------------------------------------
diff --git a/tools/conf-pseudo-distr/server/logback.xml b/tools/conf-pseudo-distr/server/logback.xml
index c27bea2..63ab23c 100644
--- a/tools/conf-pseudo-distr/server/logback.xml
+++ b/tools/conf-pseudo-distr/server/logback.xml
@@ -31,18 +31,18 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="REQUEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -50,18 +50,18 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver-requests.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver-requests.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="STATUS" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -69,8 +69,12 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver-query-status.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver-query-status.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
@@ -78,9 +82,6 @@
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="QueryExecutionStatistics" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -132,4 +133,4 @@
     <appender-ref ref="ROOT" />
     <appender-ref ref="SIFT" />
   </root>
-</configuration>
\ No newline at end of file
+</configuration>

http://git-wip-us.apache.org/repos/asf/lens/blob/d524cc24/tools/conf/client/logback.xml
----------------------------------------------------------------------
diff --git a/tools/conf/client/logback.xml b/tools/conf/client/logback.xml
index d142348..8617e17 100644
--- a/tools/conf/client/logback.xml
+++ b/tools/conf/client/logback.xml
@@ -33,14 +33,16 @@
     </encoder>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensclient.log.%d{yyyy-MM-dd}</fileNamePattern>
+      <fileNamePattern>${lens.log.dir}/lensclient.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
 
+      <timeBasedFileNamingAndTriggeringPolicy
+              class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+        <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <MaxFileSize>100MB</MaxFileSize>
-    </triggeringPolicy>
   </appender>
   <logger name="org.springframework" level="OFF"/>
   <logger name="ch.qos.logback" level="WARN"/>

http://git-wip-us.apache.org/repos/asf/lens/blob/d524cc24/tools/conf/server/logback.xml
----------------------------------------------------------------------
diff --git a/tools/conf/server/logback.xml b/tools/conf/server/logback.xml
index c27bea2..63ab23c 100644
--- a/tools/conf/server/logback.xml
+++ b/tools/conf/server/logback.xml
@@ -31,18 +31,18 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="REQUEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -50,18 +50,18 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver-requests.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver-requests.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
-
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="STATUS" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -69,8 +69,12 @@
     <append>true</append>
     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
-      <fileNamePattern>${lens.log.dir}/lensserver-query-status.log.%d{yyyy-MM-dd}</fileNamePattern>
-
+      <fileNamePattern>${lens.log.dir}/lensserver-query-status.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
+      <timeBasedFileNamingAndTriggeringPolicy
+          class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+          <!-- or whenever the file size reaches 10MB -->
+        <maxFileSize>10MB</maxFileSize>
+      </timeBasedFileNamingAndTriggeringPolicy>
       <!-- keep 30 days' worth of history -->
       <maxHistory>30</maxHistory>
     </rollingPolicy>
@@ -78,9 +82,6 @@
     <encoder>
       <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} [%X{logSegregationId}] [%t] %-5p %c - %m%n</pattern>
     </encoder>
-    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
-      <maxFileSize>100MB</maxFileSize>
-    </triggeringPolicy>
   </appender>
 
   <appender name="QueryExecutionStatistics" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -132,4 +133,4 @@
     <appender-ref ref="ROOT" />
     <appender-ref ref="SIFT" />
   </root>
-</configuration>
\ No newline at end of file
+</configuration>


[41/50] [abbrv] lens git commit: LENS-795: Look ahead is failing with partition not found if any process time partitions are absent

Posted by ra...@apache.org.
LENS-795: Look ahead is failing with partition not found if any process time partitions are absent


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

Branch: refs/heads/current-release-line
Commit: aeaae681523989c798c059bb4345aed106bd5fe1
Parents: ebb2c03
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Mon Oct 5 13:37:48 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Mon Oct 5 13:37:48 2015 +0530

----------------------------------------------------------------------
 .../PartitionRangesForPartitionColumns.java      |  6 ++++--
 .../lens/cube/parse/StorageTableResolver.java    | 19 +++++++++++++++----
 2 files changed, 19 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/aeaae681/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
index b389a8f..fa3f6ef 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/PartitionRangesForPartitionColumns.java
@@ -41,10 +41,12 @@ public class PartitionRangesForPartitionColumns extends HashMap<String, RangesPa
       .rangeUpto(partition.next().withUpdatePeriod(UpdatePeriod.values()[0])));
   }
 
-  public Set<String> toSet() {
+  public Set<String> toSet(Set<String> partColsQueried) {
     Set<String> ret = Sets.newHashSet();
     for (Map.Entry<String, RangesPartitionTimeline> entry : entrySet()) {
-      ret.add(entry.getKey() + ":" + entry.getValue().getRanges());
+      if (partColsQueried.contains(entry.getKey())) {
+        ret.add(entry.getKey() + ":" + entry.getValue().getRanges());
+      }
     }
     return ret;
   }

http://git-wip-us.apache.org/repos/asf/lens/blob/aeaae681/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
index 68ab5ab..f67fc26 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
@@ -363,7 +363,9 @@ class StorageTableResolver implements ContextRewriter {
       PartitionRangesForPartitionColumns missingParts = new PartitionRangesForPartitionColumns();
       boolean noPartsForRange = false;
       Set<String> unsupportedTimeDims = Sets.newHashSet();
+      Set<String> partColsQueried = Sets.newHashSet();
       for (TimeRange range : cubeql.getTimeRanges()) {
+        partColsQueried.add(range.getPartitionColumn());
         StringBuilder extraWhereClause = new StringBuilder();
         Set<FactPartition> rangeParts = getPartitions(cfact.fact, range, skipStorageCauses, missingParts);
         // If no partitions were found, then we'll fallback.
@@ -389,6 +391,7 @@ class StorageTableResolver implements ContextRewriter {
           if (fallBackRange == null) {
             break;
           }
+          partColsQueried.add(fallBackRange.getPartitionColumn());
           rangeParts = getPartitions(cfact.fact, fallBackRange, skipStorageCauses, missingParts);
           extraWhereClause.append(sep)
             .append(prevRange.toTimeDimWhereClause(cubeql.getAliasForTableName(cubeql.getCube()), timeDim));
@@ -433,7 +436,7 @@ class StorageTableResolver implements ContextRewriter {
         i.remove();
         continue;
       }
-      Set<String> nonExistingParts = missingParts.toSet();
+      Set<String> nonExistingParts = missingParts.toSet(partColsQueried);
       if (!nonExistingParts.isEmpty()) {
         addNonExistingParts(cfact.fact.getName(), nonExistingParts);
       }
@@ -637,8 +640,10 @@ class StorageTableResolver implements ContextRewriter {
                   for (Date date : timeRange.iterable(pPart.getPeriod(), 1)) {
                     FactPartition innerPart = new FactPartition(partCol, date, pPart.getPeriod(), pPart,
                       partWhereClauseFormat);
-                    updateFactPartitionStorageTablesFrom(fact, innerPart, pPart.getStorageTables());
-                    partitions.add(innerPart);
+                    updateFactPartitionStorageTablesFrom(fact, innerPart, pPart);
+                    if (innerPart.isFound()) {
+                      partitions.add(innerPart);
+                    }
                   }
                   log.debug("added all sub partitions blindly in pPart: {}", pPart);
                 }
@@ -678,7 +683,7 @@ class StorageTableResolver implements ContextRewriter {
         updatePeriods, addNonExistingParts, failOnPartialData, skipStorageCauses, missingPartitions);
   }
 
-  void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
+  private void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
     FactPartition part, Set<String> storageTableNames) throws LensException, HiveException, ParseException {
     for (String storageTableName : storageTableNames) {
       if (client.factPartitionExists(fact, part, storageTableName)) {
@@ -687,4 +692,10 @@ class StorageTableResolver implements ContextRewriter {
       }
     }
   }
+
+  private void updateFactPartitionStorageTablesFrom(CubeFactTable fact,
+    FactPartition part, FactPartition pPart) throws LensException, HiveException, ParseException {
+    updateFactPartitionStorageTablesFrom(fact, part, pPart.getStorageTables());
+    part.setFound(part.isFound() && pPart.isFound());
+  }
 }


[29/50] [abbrv] lens git commit: LENS-693 : Queries get purged as soon as they are finished

Posted by ra...@apache.org.
http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/common/RestAPITestUtil.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/common/RestAPITestUtil.java b/lens-server/src/test/java/org/apache/lens/server/common/RestAPITestUtil.java
index 0945598..e266ef2 100644
--- a/lens-server/src/test/java/org/apache/lens/server/common/RestAPITestUtil.java
+++ b/lens-server/src/test/java/org/apache/lens/server/common/RestAPITestUtil.java
@@ -22,9 +22,13 @@ package org.apache.lens.server.common;
 import static org.apache.lens.server.common.FormDataMultiPartFactory.createFormDataMultiPartForFact;
 import static org.apache.lens.server.common.FormDataMultiPartFactory.createFormDataMultiPartForSession;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.Invocation;
 import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
@@ -36,7 +40,9 @@ import org.apache.lens.api.metastore.XCube;
 import org.apache.lens.api.metastore.XFactTable;
 import org.apache.lens.api.query.LensQuery;
 import org.apache.lens.api.query.QueryHandle;
+import org.apache.lens.api.query.QueryResult;
 import org.apache.lens.api.query.QueryStatus;
+import org.apache.lens.api.result.LensAPIResult;
 
 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
 
@@ -53,49 +59,72 @@ public class RestAPITestUtil {
   public static LensSessionHandle openFooBarSession(final WebTarget target) {
     return openSession(target, "foo", "bar");
   }
+
   public static LensSessionHandle openSession(final WebTarget target, final String userName, final String passwd) {
     return openSession(target, userName, passwd, new LensConf());
   }
 
   public static LensSessionHandle openSession(final WebTarget target, final String userName, final String passwd,
-      final LensConf conf) {
+    final LensConf conf) {
 
     final FormDataMultiPart mp = createFormDataMultiPartForSession(Optional.<LensSessionHandle>absent(),
-        Optional.of(userName), Optional.of(passwd), Optional.of(conf));
+      Optional.of(userName), Optional.of(passwd), Optional.of(conf));
 
     return target.path("session").request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        LensSessionHandle.class);
+      LensSessionHandle.class);
   }
 
   public static Response estimate(final WebTarget target, final Optional<LensSessionHandle> sessionId,
-      final Optional<String> query) {
+    final Optional<String> query) {
 
-    return postQuery(target, sessionId, query, Optional.of("estimate"));
+    return postQuery(target, sessionId, query, Optional.of("estimate"), Optional.<LensConf>absent());
   }
 
   public static Response execute(final WebTarget target, final Optional<LensSessionHandle> sessionId,
     final Optional<String> query) {
-    return postQuery(target, sessionId, query, Optional.of("execute"));
+    return execute(target, sessionId, query, Optional.<LensConf>absent());
   }
 
-  public static Response postQuery(final WebTarget target, final Optional<LensSessionHandle> sessionId,
-      final Optional<String> query, final Optional<String> operation) {
+  public static Response execute(final WebTarget target, final Optional<LensSessionHandle> sessionId,
+    final Optional<String> query, final Optional<LensConf> lensConf) {
+    return postQuery(target, sessionId, query, Optional.of("execute"), lensConf);
+  }
+
+  public static <T> T executeAndGetHandle(final WebTarget target, final Optional<LensSessionHandle> sessionId,
+    final Optional<String> query, final Optional<LensConf> lensConf) {
+    Response resp = postQuery(target, sessionId, query, Optional.of("execute"), lensConf);
+    assertEquals(resp.getStatus(), Response.Status.OK.getStatusCode());
+    T handle = resp.readEntity(new GenericType<LensAPIResult<T>>() {}).getData();
+    assertNotNull(handle);
+    return handle;
+  }
 
-    return postQuery(target, sessionId, query, operation, new LensConf());
+  public static Response postQuery(final WebTarget target, final Optional<LensSessionHandle> sessionId,
+    final Optional<String> query, final Optional<String> operation) {
+    return postQuery(target, sessionId, query, operation, Optional.<LensConf>absent());
   }
 
   public static Response postQuery(final WebTarget target, final Optional<LensSessionHandle> sessionId,
-      final Optional<String> query, final Optional<String> operation, final LensConf conf) {
+    final Optional<String> query, final Optional<String> operation, Optional<LensConf> lensConfOptional) {
 
     FormDataMultiPart mp = FormDataMultiPartFactory
-        .createFormDataMultiPartForQuery(sessionId, query, operation, conf);
+      .createFormDataMultiPartForQuery(sessionId, query, operation, lensConfOptional.or(new LensConf()));
 
     return target.path("queryapi/queries").request(MediaType.APPLICATION_XML).post(
-        Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+      Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
   }
 
-  public static void closeSessionFailFast(final WebTarget target, final LensSessionHandle sessionId) {
+  public static LensQuery executeAndWaitForQueryToFinish(WebTarget target, LensSessionHandle lensSessionId,
+    String query, Optional<LensConf> conf, Optional<QueryStatus.Status> statusOptional) throws InterruptedException {
+    QueryHandle handle = executeAndGetHandle(target, Optional.of(lensSessionId), Optional.of(query), conf);
+    if (statusOptional.isPresent()) {
+      return waitForQueryToFinish(target, lensSessionId, handle, statusOptional.get());
+    } else {
+      return waitForQueryToFinish(target, lensSessionId, handle);
+    }
+  }
 
+  public static void closeSessionFailFast(final WebTarget target, final LensSessionHandle sessionId) {
     APIResult result = closeSession(target, sessionId);
     checkResponse(result);
   }
@@ -114,7 +143,7 @@ public class RestAPITestUtil {
   public static APIResult createCube(final WebTarget target, final LensSessionHandle sessionId, final XCube cube) {
 
     return target.path("metastore").path("cubes").queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML)
-        .post(Entity.xml(cubeObjectFactory.createXCube(cube)), APIResult.class);
+      .post(Entity.xml(cubeObjectFactory.createXCube(cube)), APIResult.class);
   }
 
   public static void createCubeFailFast(final WebTarget target, final LensSessionHandle sessionId, final XCube cube) {
@@ -123,64 +152,64 @@ public class RestAPITestUtil {
   }
 
   public static APIResult createFact(final WebTarget target, final LensSessionHandle sessionId,
-      final XFactTable factTable) {
+    final XFactTable factTable) {
 
     FormDataMultiPart mp = createFormDataMultiPartForFact(sessionId, factTable);
     return target.path("metastore").path("facts").queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML)
-        .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), APIResult.class);
+      .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE), APIResult.class);
   }
 
   public static void createFactFailFast(final WebTarget target, final LensSessionHandle sessionId,
-      final XFactTable factTable) {
+    final XFactTable factTable) {
 
     APIResult result = createFact(target, sessionId, factTable);
     checkResponse(result);
   }
 
   public static APIResult setCurrentDatabase(final WebTarget target, final LensSessionHandle sessionId,
-      final String dbName) {
+    final String dbName) {
 
     WebTarget dbTarget = target.path("metastore").path("databases/current");
     return dbTarget.queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML)
-        .put(Entity.xml(dbName),
+      .put(Entity.xml(dbName),
         APIResult.class);
   }
 
   public static void setCurrentDatabaseFailFast(final WebTarget target, final LensSessionHandle sessionId,
-      final String dbName) {
+    final String dbName) {
 
     APIResult result = setCurrentDatabase(target, sessionId, dbName);
     checkResponse(result);
   }
 
   public static APIResult createDatabase(final WebTarget target, final LensSessionHandle sessionId,
-      final String dbName) {
+    final String dbName) {
 
     WebTarget dbTarget = target.path("metastore").path("databases");
     return dbTarget.queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML)
-        .post(Entity.xml(dbName), APIResult.class);
+      .post(Entity.xml(dbName), APIResult.class);
   }
 
   public static void createDatabaseFailFast(final WebTarget target, final LensSessionHandle sessionId,
-      final String dbName) {
+    final String dbName) {
 
     APIResult result = createDatabase(target, sessionId, dbName);
     checkResponse(result);
   }
 
   public static void createAndSetCurrentDbFailFast(final WebTarget target, final LensSessionHandle sessionId,
-      final String dbName) {
+    final String dbName) {
 
     createDatabaseFailFast(target, sessionId, dbName);
     setCurrentDatabaseFailFast(target, sessionId, dbName);
   }
 
   public static APIResult dropDatabaseFailFast(final WebTarget target, final LensSessionHandle sessionId,
-      String dbName) {
+    String dbName) {
 
     WebTarget dbTarget = target.path("metastore").path("databases").path(dbName);
     return dbTarget.queryParam("cascade", "true")
-        .queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML).delete(APIResult.class);
+      .queryParam("sessionid", sessionId).request(MediaType.APPLICATION_XML).delete(APIResult.class);
   }
 
   private static void checkResponse(final APIResult result) {
@@ -191,22 +220,45 @@ public class RestAPITestUtil {
 
   public static LensQuery waitForQueryToFinish(final WebTarget target, final LensSessionHandle lensSessionHandle,
     final QueryHandle handle) throws InterruptedException {
-
-    LensQuery lensQuery = getLensQuery(target, lensSessionHandle, handle);
-
-    QueryStatus stat = lensQuery.getStatus();
-    while (!stat.finished()) {
-      lensQuery = getLensQuery(target, lensSessionHandle, handle);
-      stat = lensQuery.getStatus();
+    LensQuery ctx = getLensQuery(target, lensSessionHandle, handle);
+    while (!ctx.getStatus().finished()) {
+      ctx = getLensQuery(target, lensSessionHandle, handle);
       Thread.sleep(1000);
     }
+    return ctx;
+  }
+
+  public static LensQuery waitForQueryToFinish(final WebTarget target, final LensSessionHandle lensSessionHandle,
+    final QueryHandle handle, QueryStatus.Status status) throws InterruptedException {
+    LensQuery lensQuery = waitForQueryToFinish(target, lensSessionHandle, handle);
+    assertEquals(lensQuery.getStatus().getStatus(), status);
     return lensQuery;
   }
 
   public static LensQuery getLensQuery(final WebTarget target, final LensSessionHandle lensSessionHandle,
     final QueryHandle handle) {
-
     return target.path("queryapi/queries").path(handle.toString()).queryParam("sessionid", lensSessionHandle).request()
-        .get(LensQuery.class);
+      .get(LensQuery.class);
+  }
+
+  public static QueryResult getLensQueryResult(final WebTarget target, final LensSessionHandle lensSessionHandle,
+    final QueryHandle handle) {
+    return target.path("queryapi/queries").path(handle.toString()).path("resultset")
+      .queryParam("sessionid", lensSessionHandle).request().get(QueryResult.class);
+  }
+
+  public static Response getLensQueryHttpResult(final WebTarget target, final LensSessionHandle lensSessionHandle,
+    final QueryHandle handle) {
+    return target.path("queryapi/queries").path(handle.toString()).path("httpresultset")
+      .queryParam("sessionid", lensSessionHandle).request().get(Response.class);
+  }
+
+  public static LensConf getLensConf(Object... args) {
+    assertEquals(args.length % 2, 0);
+    LensConf conf = new LensConf();
+    for (int i = 0; i < args.length; i += 2) {
+      conf.addProperty(args[i], args[i + 1]);
+    }
+    return conf;
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/query/TestEventService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestEventService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestEventService.java
index b8012be..1dab35e 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestEventService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestEventService.java
@@ -92,7 +92,6 @@ public class TestEventService {
    * the genericEvent event occurs, that object's appropriate
    * method is invoked.
    *
-   * @see GenericEventEvent
    */
   class GenericEventListener extends AsyncEventListener<LensEvent> {
 
@@ -119,7 +118,6 @@ public class TestEventService {
    * the mockFailed event occurs, that object's appropriate
    * method is invoked.
    *
-   * @see MockFailedEvent
    */
   class MockFailedListener implements LensEventListener<QueryFailed> {
 
@@ -146,7 +144,6 @@ public class TestEventService {
    * the mockEnded event occurs, that object's appropriate
    * method is invoked.
    *
-   * @see MockEndedEvent
    */
   class MockEndedListener implements LensEventListener<QueryEnded> {
 
@@ -290,7 +287,7 @@ public class TestEventService {
    */
   @Test
   public void testAddListener() {
-    int listenersBefore = ((EventServiceImpl) service).getEventListeners().keySet().size();
+    int listenersBefore = service.getEventListeners().keySet().size();
     genericEventListener = new GenericEventListener();
     service.addListenerForType(genericEventListener, LensEvent.class);
     endedListener = new MockEndedListener();
@@ -417,8 +414,10 @@ public class TestEventService {
     QueryHandle query = new QueryHandle(UUID.randomUUID());
     String user = "user";
     long now = System.currentTimeMillis();
-    QueryFailed failed = new QueryFailed(now, QueryStatus.Status.RUNNING, QueryStatus.Status.FAILED, query, user, null);
-    QuerySuccess success = new QuerySuccess(now, QueryStatus.Status.RUNNING, QueryStatus.Status.SUCCESSFUL, query);
+    QueryFailed failed
+      = new QueryFailed(null, now, QueryStatus.Status.RUNNING, QueryStatus.Status.FAILED, query, user, null);
+    QuerySuccess success
+      = new QuerySuccess(null, now, QueryStatus.Status.RUNNING, QueryStatus.Status.SUCCESSFUL, query);
     QueuePositionChange positionChange = new QueuePositionChange(now, 1, 0, query);
 
     try {

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/query/TestQueryEndEmailNotifier.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryEndEmailNotifier.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryEndEmailNotifier.java
index 82ce205..3bb90ef 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryEndEmailNotifier.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryEndEmailNotifier.java
@@ -18,28 +18,25 @@
  */
 package org.apache.lens.server.query;
 
-import static org.apache.lens.server.common.RestAPITestUtil.execute;
-import static org.apache.lens.server.common.RestAPITestUtil.waitForQueryToFinish;
+import static org.apache.lens.server.common.RestAPITestUtil.*;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.apache.lens.api.LensConf;
 import org.apache.lens.api.LensSessionHandle;
-import org.apache.lens.api.query.LensQuery;
+import org.apache.lens.api.query.InMemoryQueryResult;
 import org.apache.lens.api.query.QueryHandle;
-import org.apache.lens.api.query.QueryStatus;
+import org.apache.lens.api.query.QueryResult;
 import org.apache.lens.api.query.QueryStatus.Status;
 import org.apache.lens.api.result.LensAPIResult;
 import org.apache.lens.server.LensJerseyTest;
@@ -52,16 +49,10 @@ import org.apache.lens.server.common.TestResourceFile;
 import org.apache.hadoop.hive.conf.HiveConf;
 
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.media.multipart.FormDataBodyPart;
-import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
-import org.glassfish.jersey.media.multipart.FormDataMultiPart;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
 import org.subethamail.wiser.Wiser;
 import org.subethamail.wiser.WiserMessage;
-import org.testng.Assert;
-import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
+import org.testng.annotations.*;
 
 import com.google.common.base.Optional;
 
@@ -93,7 +84,7 @@ public class TestQueryEndEmailNotifier extends LensJerseyTest {
     wiser.setHostname("localhost");
     wiser.setPort(25000);
     queryService = LensServices.get().getService(QueryExecutionService.NAME);
-    Map<String, String> sessionconf = new HashMap<String, String>();
+    Map<String, String> sessionconf = new HashMap<>();
     sessionconf.put("test.session.key", "svalue");
     sessionconf.put(LensConfConstants.QUERY_MAIL_NOTIFY, "true");
     sessionconf.put(LensConfConstants.QUERY_RESULT_EMAIL_CC, "foo1@localhost,foo2@localhost,foo3@localhost");
@@ -101,6 +92,12 @@ public class TestQueryEndEmailNotifier extends LensJerseyTest {
     // automatically
     createTable(TEST_TABLE);
     loadData(TEST_TABLE, TestResourceFile.TEST_DATA2_FILE.getValue());
+    wiser.start();
+  }
+
+  @BeforeMethod
+  public void clearWiserMessages() {
+    wiser.getMessages().clear();
   }
 
   /*
@@ -110,6 +107,7 @@ public class TestQueryEndEmailNotifier extends LensJerseyTest {
    */
   @AfterTest
   public void tearDown() throws Exception {
+    wiser.stop();
     dropTable(TEST_TABLE);
     queryService.closeSession(lensSessionId);
     super.tearDown();
@@ -171,28 +169,29 @@ public class TestQueryEndEmailNotifier extends LensJerseyTest {
 
   private QueryHandle launchAndWaitForQuery(LensConf conf, String query, Status expectedStatus)
     throws InterruptedException {
-    final WebTarget target = target().path("queryapi/queries");
-    final FormDataMultiPart mp = new FormDataMultiPart();
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), query));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "execute"));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), conf,
-      MediaType.APPLICATION_XML_TYPE));
-    final QueryHandle handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-      new GenericType<LensAPIResult<QueryHandle>>(){}).getData();
+    return executeAndWaitForQueryToFinish(target(), lensSessionId, query, Optional.of(conf),
+      Optional.of(expectedStatus)).getQueryHandle();
+  }
+
+  private WiserMessage getMessage() throws InterruptedException {
+    List<WiserMessage> messages = new ArrayList<>();
+    for (int i = 0; i < NUM_ITERS; i++) {
+      messages = wiser.getMessages();
+      if (messages.size() >= 4) {
+        break;
+      }
+      Thread.sleep(2000);
+    }
+    assertEquals(messages.size(), 4);
+    return messages.get(0);
+  }
 
-    Assert.assertNotNull(handle);
-    LensQuery ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request()
-      .get(LensQuery.class);
-    QueryStatus stat = ctx.getStatus();
-    while (!stat.finished()) {
-      ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = ctx.getStatus();
-      Thread.sleep(1000);
+  private void assertKeywordsContains(Object o, Object... keywords) {
+    String string = o.toString();
+    for (Object keyword : keywords) {
+      // Mail message converts \n to \r\n
+      assertTrue(string.contains(keyword.toString().replaceAll("\\n", "\r\n")), o + " doesn't contain " + keyword);
     }
-    Assert.assertEquals(ctx.getStatus().getStatus(), expectedStatus);
-    return handle;
   }
 
   /**
@@ -201,91 +200,70 @@ public class TestQueryEndEmailNotifier extends LensJerseyTest {
    * @throws InterruptedException the interrupted exception
    */
   @Test
-  public void testEmailNotification() throws InterruptedException {
-    wiser.start();
-
-    LensConf conf = new LensConf();
-
+  public void testLaunchFailure() throws InterruptedException {
     // launch failure
     final Response response = execute(target(), Optional.of(lensSessionId), Optional.of("select fail from non_exist"));
     assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
     QueryHandle handle = response.readEntity(new GenericType<LensAPIResult<QueryHandle>>() {}).getData();
-    LensQuery lensQuery = waitForQueryToFinish(target(), lensSessionId, handle);
-
-    List<WiserMessage> messages = new ArrayList<WiserMessage>();
-    for (int i = 0; i < NUM_ITERS; i++) {
-      messages = wiser.getMessages();
-      if (messages.size() >= 4) {
-        break;
-      }
-      Thread.sleep(2000);
-    }
-
-    Assert.assertEquals(messages.size(), 4);
-    Assert.assertTrue(messages.get(0).toString().contains(handle.toString()));
-    Assert.assertTrue(messages.get(0).toString().contains("Launching query failed"));
-    Assert.assertTrue(messages.get(0).toString().contains("Reason"));
+    assertKeywordsContains(getMessage(), handle, "Launching query failed", "Reason");
+  }
 
+  @Test
+  public void testFormattingFailure() throws InterruptedException {
     // formatting failure
-    conf = new LensConf();
-    conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_SET, "true");
-    conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "false");
-    conf.addProperty(LensConfConstants.QUERY_OUTPUT_SERDE, "NonexistentSerde.class");
-    handle = launchAndWaitForQuery(conf, "select ID, IDSTR from " + TEST_TABLE,
-      QueryStatus.Status.FAILED);
-
-    messages = new ArrayList<WiserMessage>();
-    for (int i = 0; i < NUM_ITERS; i++) {
-      messages = wiser.getMessages();
-      if (messages.size() >= 8) {
-        break;
-      }
-      Thread.sleep(2000);
-    }
-
-    Assert.assertEquals(messages.size(), 8);
-    Assert.assertTrue(messages.get(4).toString().contains(handle.toString()));
-    Assert.assertTrue(messages.get(4).toString().contains("Result formatting failed!"));
-    Assert.assertTrue(messages.get(4).toString().contains("Reason"));
+    LensConf conf = getLensConf(
+      LensConfConstants.QUERY_PERSISTENT_RESULT_SET, "true",
+      LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "false",
+      LensConfConstants.QUERY_OUTPUT_SERDE, "NonexistentSerde.class");
+    QueryHandle handle = launchAndWaitForQuery(conf, "select ID, IDSTR from " + TEST_TABLE, Status.FAILED);
+    assertKeywordsContains(getMessage(), handle, "Result formatting failed!", "Reason");
+  }
 
+  @Test
+  public void testExecutionFailure() throws InterruptedException {
     // execution failure
-    conf = new LensConf();
-    conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "true");
-    conf.addProperty(HiveConf.ConfVars.COMPRESSRESULT.name(), "true");
-    conf.addProperty("mapred.compress.map.output", "true");
-    conf.addProperty("mapred.map.output.compression.codec", "nonexisting");
-    handle = launchAndWaitForQuery(conf, "select count(ID) from " + TEST_TABLE, QueryStatus.Status.FAILED);
-    messages = new ArrayList<WiserMessage>();
-    for (int i = 0; i < NUM_ITERS; i++) {
-      messages = wiser.getMessages();
-      if (messages.size() >= 8) {
-        break;
-      }
-      Thread.sleep(2000);
-    }
+    LensConf conf = getLensConf(
+      LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "true",
+      HiveConf.ConfVars.COMPRESSRESULT.name(), "true",
+      "mapred.compress.map.output", "true",
+      "mapred.map.output.compression.codec", "nonexisting");
+    QueryHandle handle = launchAndWaitForQuery(conf, "select count(ID) from " + TEST_TABLE, Status.FAILED);
+    assertKeywordsContains(getMessage(), handle, "Query execution failed!", "Reason");
+  }
 
-    Assert.assertEquals(messages.size(), 12);
-    Assert.assertTrue(messages.get(8).toString().contains(handle.toString()));
-    Assert.assertTrue(messages.get(8).toString().contains("Query execution failed!"));
-    Assert.assertTrue(messages.get(8).toString().contains("Reason"));
+  @DataProvider(name = "success-tests")
+  public Object[][] persistenceConfigDataProvider() {
+    return new Object[][]{
+      {false, false, },
+      {true, false, },
+      {false, true, },
+      {true, true, },
+    };
+  }
 
+  @Test(dataProvider = "success-tests")
+  public void testSuccessfulQuery(Boolean lensPersistence, Boolean driverPersistence) throws InterruptedException {
     // successful query
-    conf = new LensConf();
-    conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_SET, "true");
-    conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "true");
-    handle = launchAndWaitForQuery(conf, "select ID, IDSTR from " + TEST_TABLE, QueryStatus.Status.SUCCESSFUL);
-    messages = new ArrayList<WiserMessage>();
-    for (int i = 0; i < NUM_ITERS; i++) {
-      messages = wiser.getMessages();
-      if (messages.size() >= 16) {
-        break;
-      }
-      Thread.sleep(2000);
+    LensConf conf = getLensConf(
+      LensConfConstants.QUERY_PERSISTENT_RESULT_SET, lensPersistence,
+      LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, driverPersistence);
+    QueryHandle handle = launchAndWaitForQuery(conf, "select ID, IDSTR from " + TEST_TABLE, Status.SUCCESSFUL);
+    String expectedKeywords;
+    if (lensPersistence || driverPersistence) {
+      QueryResult result = getLensQueryResult(target(), lensSessionId, handle);
+      expectedKeywords = result.toPrettyString();
+    } else {
+      expectedKeywords = InMemoryQueryResult.DECLARATION;
+    }
+    WiserMessage message = getMessage();
+    assertKeywordsContains(message, handle, "Query SUCCESSFUL", expectedKeywords);
+    if (lensPersistence) {
+      assertKeywordsContains(message, new String[]{"Downloadable from", "httpresultset"});
+      assertEquals(getLensQueryHttpResult(target(), lensSessionId, handle).getStatus(),
+        Response.Status.OK.getStatusCode());
+    } else {
+      assertEquals(getLensQueryHttpResult(target(), lensSessionId, handle).getStatus(),
+        Response.Status.NOT_FOUND.getStatusCode());
     }
-    Assert.assertEquals(messages.size(), 16);
-    Assert.assertTrue(messages.get(12).toString().contains(handle.toString()));
-    Assert.assertTrue(messages.get(12).toString().contains("Query  SUCCESSFUL"));
-    Assert.assertTrue(messages.get(12).toString().contains("Result available at"));
-    wiser.stop();
   }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
index fa8d6ee..ea75ffb 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestQueryService.java
@@ -18,10 +18,9 @@
  */
 package org.apache.lens.server.query;
 
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
+import static javax.ws.rs.core.Response.Status.*;
 
-import static org.apache.lens.server.common.RestAPITestUtil.execute;
-import static org.apache.lens.server.common.RestAPITestUtil.waitForQueryToFinish;
+import static org.apache.lens.server.common.RestAPITestUtil.*;
 
 import static org.testng.Assert.*;
 
@@ -31,7 +30,10 @@ import java.util.*;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.*;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
 
 import org.apache.lens.api.APIResult;
 import org.apache.lens.api.LensConf;
@@ -39,7 +41,9 @@ import org.apache.lens.api.LensSessionHandle;
 import org.apache.lens.api.jaxb.LensJAXBContextResolver;
 import org.apache.lens.api.query.*;
 import org.apache.lens.api.query.QueryStatus.Status;
-import org.apache.lens.api.result.*;
+import org.apache.lens.api.result.LensAPIResult;
+import org.apache.lens.api.result.LensErrorTO;
+import org.apache.lens.api.result.QueryCostTO;
 import org.apache.lens.cube.error.LensCubeErrorCode;
 import org.apache.lens.driver.hive.HiveDriver;
 import org.apache.lens.server.LensJerseyTest;
@@ -62,17 +66,24 @@ import org.apache.lens.server.session.HiveSessionService;
 import org.apache.lens.server.session.LensSessionImpl;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.*;
+import org.apache.hadoop.fs.FSDataInputStream;
+import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.IOUtils;
 
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.media.multipart.*;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
 import org.glassfish.jersey.test.TestProperties;
-import org.testng.annotations.*;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
 
 import com.codahale.metrics.MetricRegistry;
-
 import com.google.common.base.Optional;
 import lombok.extern.slf4j.Slf4j;
 
@@ -102,6 +113,7 @@ public class TestQueryService extends LensJerseyTest {
       return classes;
     }
   }
+
   /*
    * (non-Javadoc)
    *
@@ -218,14 +230,14 @@ public class TestQueryService extends LensJerseyTest {
     LensConf conf = new LensConf();
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
     mp.bodyPart(
-        new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select ID from non_exist_table"));
+      new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select ID from non_exist_table"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "execute"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), conf,
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
     final Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
-    assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    assertEquals(response.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode());
   }
 
   /**
@@ -235,19 +247,13 @@ public class TestQueryService extends LensJerseyTest {
    */
   @Test
   public void testLaunchFail() throws InterruptedException {
-
-    final Response response = execute(target(), Optional.of(lensSessionId), Optional.of("select fail from non_exist"));
-    assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
-
-    QueryHandle handle = response.readEntity(new GenericType<LensAPIResult<QueryHandle>>() {}).getData();
-    LensQuery lensQuery = waitForQueryToFinish(target(), lensSessionId, handle);
-
+    LensQuery lensQuery = executeAndWaitForQueryToFinish(target(), lensSessionId, "select fail from non_exist",
+      Optional.<LensConf>absent(), Optional.of(Status.FAILED));
     assertTrue(lensQuery.getSubmissionTime() > 0);
     assertEquals(lensQuery.getLaunchTime(), 0);
     assertEquals(lensQuery.getDriverStartTime(), 0);
     assertEquals(lensQuery.getDriverFinishTime(), 0);
     assertTrue(lensQuery.getFinishTime() > 0);
-    assertEquals(lensQuery.getStatus().getStatus(), QueryStatus.Status.FAILED);
   }
 
   // test with execute async post, get all queries, get query context,
@@ -262,22 +268,13 @@ public class TestQueryService extends LensJerseyTest {
   public void testQueriesAPI() throws InterruptedException {
     // test post execute op
     final WebTarget target = target().path("queryapi/queries");
-    final FormDataMultiPart mp = new FormDataMultiPart();
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-      MediaType.APPLICATION_XML_TYPE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select ID from " + TEST_TABLE));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "execute"));
-    mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-      MediaType.APPLICATION_XML_TYPE));
 
     long queuedQueries = metricsSvc.getQueuedQueries();
     long runningQueries = metricsSvc.getRunningQueries();
     long finishedQueries = metricsSvc.getFinishedQueries();
 
-    final QueryHandle handle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryHandle>>() {
-        }).getData();
-    assertNotNull(handle);
+    QueryHandle handle = executeAndGetHandle(target(), Optional.of(lensSessionId), Optional.of("select ID from "
+      + TEST_TABLE), Optional.<LensConf>absent());
 
     // Get all queries
     // XML
@@ -285,7 +282,7 @@ public class TestQueryService extends LensJerseyTest {
       .get(new GenericType<List<QueryHandle>>() {});
     assertTrue(allQueriesXML.size() >= 1);
 
-    List<QueryHandle> allQueries = (List<QueryHandle>) target.queryParam("sessionid", lensSessionId).request()
+    List<QueryHandle> allQueries = target.queryParam("sessionid", lensSessionId).request()
       .get(new GenericType<List<QueryHandle>>() {});
     assertTrue(allQueries.size() >= 1);
     assertTrue(allQueries.contains(handle));
@@ -375,7 +372,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPlan plan2 = ptarget.request().post(Entity.entity(mp2, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+      new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
     assertEquals(plan2.getTablesQueried().size(), 1);
     assertTrue(plan2.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
     assertNotNull(plan2.getPrepareHandle());
@@ -395,33 +392,33 @@ public class TestQueryService extends LensJerseyTest {
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-        + TEST_TABLE));
+      + TEST_TABLE));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
 
     final Response responseExplain = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
 
-    assertEquals(responseExplain.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    assertEquals(responseExplain.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode());
 
     // Test explain and prepare
     final WebTarget ptarget = target().path("queryapi/preparedqueries");
 
     final FormDataMultiPart mp2 = new FormDataMultiPart();
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("sessionid").build(), lensSessionId,
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("query").build(), "select NO_ID from "
-        + TEST_TABLE));
+      + TEST_TABLE));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("operation").build(), "explain_and_prepare"));
     mp2.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
 
     final Response responseExplainAndPrepare = target.request().post(
-        Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
+      Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
 
-    assertEquals(responseExplainAndPrepare.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    assertEquals(responseExplainAndPrepare.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode());
   }
 
   // post to preparedqueries
@@ -451,7 +448,7 @@ public class TestQueryService extends LensJerseyTest {
       MediaType.APPLICATION_XML_TYPE));
 
     final QueryPrepareHandle pHandle = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-        new GenericType<LensAPIResult<QueryPrepareHandle>>() {}).getData();
+      new GenericType<LensAPIResult<QueryPrepareHandle>>() {}).getData();
 
     // Get all prepared queries
     List<QueryPrepareHandle> allQueries = (List<QueryPrepareHandle>) target.queryParam("sessionid", lensSessionId)
@@ -493,32 +490,11 @@ public class TestQueryService extends LensJerseyTest {
       .post(Entity.entity(confpart, MediaType.MULTIPART_FORM_DATA_TYPE), QueryHandle.class);
     assertNotEquals(handle1, handle2);
 
-    LensQuery ctx1 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-      .request().get(LensQuery.class);
+    LensQuery ctx1 = waitForQueryToFinish(target(), lensSessionId, handle1, Status.SUCCESSFUL);
     assertEquals(ctx1.getQueryName().toLowerCase(), "testquery1");
-    // wait till the query finishes
-    QueryStatus stat = ctx1.getStatus();
-    while (!stat.finished()) {
-      ctx1 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-        .request().get(LensQuery.class);
-      stat = ctx1.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx1.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
 
-    LensQuery ctx2 = target().path("queryapi/queries").path(handle2.toString()).queryParam("sessionid", lensSessionId)
-      .request().get(LensQuery.class);
-    assertNotNull(ctx2);
+    LensQuery ctx2 = waitForQueryToFinish(target(), lensSessionId, handle2, Status.SUCCESSFUL);
     assertEquals(ctx2.getQueryName().toLowerCase(), "testqueryname2");
-    // wait till the query finishes
-    stat = ctx2.getStatus();
-    while (!stat.finished()) {
-      ctx2 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-        .request().get(LensQuery.class);
-      stat = ctx2.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx1.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
 
     // destroy prepared
     APIResult result = target.path(pHandle.toString()).queryParam("sessionid", lensSessionId).request()
@@ -550,7 +526,7 @@ public class TestQueryService extends LensJerseyTest {
 
     final QueryPlan plan = target.request()
       .post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE),
-          new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
+        new GenericType<LensAPIResult<QueryPlan>>() {}).getData();
 
     assertEquals(plan.getTablesQueried().size(), 1);
     assertTrue(plan.getTablesQueried().get(0).endsWith(TEST_TABLE.toLowerCase()));
@@ -588,29 +564,8 @@ public class TestQueryService extends LensJerseyTest {
       .post(Entity.entity(confpart, MediaType.MULTIPART_FORM_DATA_TYPE), QueryHandle.class);
     assertNotEquals(handle1, handle2);
 
-    LensQuery ctx1 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-      .request().get(LensQuery.class);
-    // wait till the query finishes
-    QueryStatus stat = ctx1.getStatus();
-    while (!stat.finished()) {
-      ctx1 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-        .request().get(LensQuery.class);
-      stat = ctx1.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx1.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
-
-    LensQuery ctx2 = target().path("queryapi/queries").path(handle2.toString()).queryParam("sessionid", lensSessionId)
-      .request().get(LensQuery.class);
-    // wait till the query finishes
-    stat = ctx2.getStatus();
-    while (!stat.finished()) {
-      ctx2 = target().path("queryapi/queries").path(handle1.toString()).queryParam("sessionid", lensSessionId)
-        .request().get(LensQuery.class);
-      stat = ctx2.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx1.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, handle1, Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, handle2, Status.SUCCESSFUL);
 
     // destroy prepared
     APIResult result = target.path(plan.getPrepareHandle().toString()).queryParam("sessionid", lensSessionId).request()
@@ -660,7 +615,7 @@ public class TestQueryService extends LensJerseyTest {
     assertTrue(lensQuery.getStatus().getStatus().equals(Status.QUEUED)
       || lensQuery.getStatus().getStatus().equals(Status.LAUNCHED)
       || lensQuery.getStatus().getStatus().equals(Status.RUNNING)
-      || lensQuery.getStatus().getStatus().equals(Status.SUCCESSFUL));
+      || lensQuery.getStatus().getStatus().equals(Status.SUCCESSFUL), lensQuery.getStatus().toString());
 
     // wait till the query finishes
     QueryStatus stat = lensQuery.getStatus();
@@ -729,14 +684,7 @@ public class TestQueryService extends LensJerseyTest {
       new GenericType<LensAPIResult<QueryHandle>>() {}).getData();
 
     // Get query
-    lensQuery = target.path(handle3.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-    // wait till the query finishes
-    stat = lensQuery.getStatus();
-    while (!stat.finished()) {
-      lensQuery = target.path(handle3.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = lensQuery.getStatus();
-      Thread.sleep(1000);
-    }
+    waitForQueryToFinish(target(), lensSessionId, handle3, Status.SUCCESSFUL);
     validateHttpEndPoint(target(), null, handle3, null);
   }
 
@@ -918,7 +866,7 @@ public class TestQueryService extends LensJerseyTest {
       List<String> actualRows = Arrays.asList(result.split("\n"));
       validatePersistentResult(actualRows);
     } else {
-      assertEquals(Response.Status.SEE_OTHER.getStatusCode(), response.getStatus());
+      assertEquals(SEE_OTHER.getStatusCode(), response.getStatus());
       assertTrue(response.getHeaderString("Location").contains(redirectUrl));
     }
   }
@@ -934,10 +882,10 @@ public class TestQueryService extends LensJerseyTest {
     try {
       Response response = parent.path("queryapi/queries/" + handle.toString() + "/httpresultset")
         .queryParam("sessionid", lensSessionId).request().get();
-      if (Response.Status.NOT_FOUND.getStatusCode() != response.getStatus()) {
+      if (NOT_FOUND.getStatusCode() != response.getStatus()) {
         fail("Expected not found excepiton, but got:" + response.getStatus());
       }
-      assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
+      assertEquals(response.getStatus(), NOT_FOUND.getStatusCode());
     } catch (NotFoundException e) {
       // expected
       log.error("Resource not found.", e);
@@ -975,27 +923,13 @@ public class TestQueryService extends LensJerseyTest {
     assertNotNull(handle);
 
     // Get query
-    LensQuery ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request()
-      .get(LensQuery.class);
-    assertTrue(ctx.getStatus().getStatus().equals(Status.QUEUED)
-      || ctx.getStatus().getStatus().equals(Status.LAUNCHED) || ctx.getStatus().getStatus().equals(Status.RUNNING)
-      || ctx.getStatus().getStatus().equals(Status.SUCCESSFUL));
-
-    // wait till the query finishes
-    QueryStatus stat = ctx.getStatus();
-    while (!stat.finished()) {
-      ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = ctx.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, handle, Status.SUCCESSFUL);
 
     // fetch results
     validateResultSetMetadata(handle, "",
       new String[][]{{"ID", "INT"}, {"IDSTR", "STRING"}},
       target(), lensSessionId);
 
-
     InMemoryQueryResult resultset = target.path(handle.toString()).path("resultset")
       .queryParam("sessionid", lensSessionId).request().get(InMemoryQueryResult.class);
     validateInmemoryResult(resultset);
@@ -1030,20 +964,7 @@ public class TestQueryService extends LensJerseyTest {
     assertNotNull(dropHandle);
 
     // Get query
-    LensQuery ctx = target.path(dropHandle.toString()).queryParam("sessionid", lensSessionId).request()
-      .get(LensQuery.class);
-    assertTrue(ctx.getStatus().getStatus().equals(Status.QUEUED)
-      || ctx.getStatus().getStatus().equals(Status.LAUNCHED) || ctx.getStatus().getStatus().equals(Status.RUNNING)
-      || ctx.getStatus().getStatus().equals(Status.SUCCESSFUL));
-
-    // wait till the query finishes
-    QueryStatus stat = ctx.getStatus();
-    while (!stat.finished()) {
-      ctx = target.path(dropHandle.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = ctx.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, dropHandle, Status.SUCCESSFUL);
 
     final FormDataMultiPart mp = new FormDataMultiPart();
     conf = new LensConf();
@@ -1061,19 +982,7 @@ public class TestQueryService extends LensJerseyTest {
     assertNotNull(handle);
 
     // Get query
-    ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-    assertTrue(ctx.getStatus().getStatus().equals(Status.QUEUED)
-      || ctx.getStatus().getStatus().equals(Status.LAUNCHED) || ctx.getStatus().getStatus().equals(Status.RUNNING)
-      || ctx.getStatus().getStatus().equals(Status.SUCCESSFUL));
-
-    // wait till the query finishes
-    stat = ctx.getStatus();
-    while (!stat.finished()) {
-      ctx = target.path(handle.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = ctx.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, handle, Status.SUCCESSFUL);
 
     String select = "SELECT * FROM temp_output";
     final FormDataMultiPart fetch = new FormDataMultiPart();
@@ -1089,16 +998,7 @@ public class TestQueryService extends LensJerseyTest {
     assertNotNull(handle2);
 
     // Get query
-    ctx = target.path(handle2.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-
-    // wait till the query finishes
-    stat = ctx.getStatus();
-    while (!stat.finished()) {
-      ctx = target.path(handle2.toString()).queryParam("sessionid", lensSessionId).request().get(LensQuery.class);
-      stat = ctx.getStatus();
-      Thread.sleep(1000);
-    }
-    assertEquals(ctx.getStatus().getStatus(), QueryStatus.Status.SUCCESSFUL);
+    waitForQueryToFinish(target(), lensSessionId, handle2, Status.SUCCESSFUL);
 
     // fetch results
     validateResultSetMetadata(handle2, "temp_output.", new String[][]{{"ID", "INT"}, {"IDSTR", "STRING"}},
@@ -1236,10 +1136,10 @@ public class TestQueryService extends LensJerseyTest {
     // set a timeout value enough for tests
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("timeoutmillis").build(), "300000"));
     mp.bodyPart(new FormDataBodyPart(FormDataContentDisposition.name("conf").fileName("conf").build(), new LensConf(),
-        MediaType.APPLICATION_XML_TYPE));
+      MediaType.APPLICATION_XML_TYPE));
 
     Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
-    assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+    assertEquals(response.getStatus(), INTERNAL_SERVER_ERROR.getStatusCode());
   }
 
   /**
@@ -1423,7 +1323,7 @@ public class TestQueryService extends LensJerseyTest {
 
 
     LensErrorTO expectedLensErrorTO = LensErrorTO.composedOf(
-        LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo().getErrorCode(),
+      LensCubeErrorCode.NEITHER_CUBE_NOR_DIMENSION.getLensErrorInfo().getErrorCode(),
       "Neither cube nor dimensions accessed in the query", TestDataUtils.MOCK_STACK_TRACE);
     ErrorResponseExpectedData expectedData = new ErrorResponseExpectedData(BAD_REQUEST, expectedLensErrorTO);
 
@@ -1499,6 +1399,7 @@ public class TestQueryService extends LensJerseyTest {
         "lens.MethodMetricGauge.TestQueryService-testEstimateGauges-PARALLEL_ESTIMATE")),
       reg.getGauges().keySet().toString());
   }
+
   @Test
   public void testQueryRejection() throws InterruptedException, IOException {
     final WebTarget target = target().path("queryapi/queries");
@@ -1515,4 +1416,40 @@ public class TestQueryService extends LensJerseyTest {
     Response response = target.request().post(Entity.entity(mp, MediaType.MULTIPART_FORM_DATA_TYPE));
     assertEquals(response.getStatus(), 400);
   }
+
+  /**
+   * Test query purger
+   *
+   * @throws InterruptedException the interrupted exception
+   * @throws IOException          Signals that an I/O exception has occurred.
+   */
+  @Test
+  public void testQueryPurger() throws InterruptedException, IOException {
+    waitForPurge();
+    LensConf conf = getLensConf(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "false");
+    // test post execute op
+    LensQuery ctx1 = executeAndWaitForQueryToFinish(target(), lensSessionId,
+      "select ID, IDSTR from " + TEST_TABLE,
+      Optional.of(conf), Optional.of(Status.SUCCESSFUL));
+    LensQuery ctx2 = executeAndWaitForQueryToFinish(target(), lensSessionId,
+      "select ID, IDSTR from " + TEST_TABLE,
+      Optional.of(conf), Optional.of(Status.SUCCESSFUL));
+    LensQuery ctx3 = executeAndWaitForQueryToFinish(target(), lensSessionId,
+      "select ID, IDSTR from " + TEST_TABLE,
+      Optional.of(conf), Optional.of(Status.SUCCESSFUL));
+    waitForPurge(3, queryService.finishedQueries);
+    assertEquals(queryService.finishedQueries.size(), 3);
+    getLensQueryResult(target(), lensSessionId, ctx3.getQueryHandle());
+    waitForPurge(2, queryService.finishedQueries);
+    assertTrue(queryService.finishedQueries.size() == 2);
+    getLensQueryResult(target(), lensSessionId, ctx2.getQueryHandle());
+    waitForPurge(1, queryService.finishedQueries);
+    assertTrue(queryService.finishedQueries.size() == 1);
+    getLensQueryResult(target(), lensSessionId, ctx1.getQueryHandle());
+  }
+
+  @AfterMethod
+  private void waitForPurge() throws InterruptedException {
+    waitForPurge(0, queryService.finishedQueries);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/java/org/apache/lens/server/query/TestResultFormatting.java
----------------------------------------------------------------------
diff --git a/lens-server/src/test/java/org/apache/lens/server/query/TestResultFormatting.java b/lens-server/src/test/java/org/apache/lens/server/query/TestResultFormatting.java
index 98a658e..987129c 100644
--- a/lens-server/src/test/java/org/apache/lens/server/query/TestResultFormatting.java
+++ b/lens-server/src/test/java/org/apache/lens/server/query/TestResultFormatting.java
@@ -130,9 +130,9 @@ public class TestResultFormatting extends LensJerseyTest {
     conf.addProperty(LensConfConstants.QUERY_OUTPUT_SERDE, LazySimpleSerDe.class.getCanonicalName());
     testResultFormatter(conf, QueryStatus.Status.SUCCESSFUL, false, null);
 
-    conf.addProperty(LensConfConstants.RESULT_FS_READ_URL, "filereadurl://");
+    queryService.conf.set(LensConfConstants.RESULT_FS_READ_URL, "filereadurl://");
     testResultFormatter(conf, QueryStatus.Status.SUCCESSFUL, false, "filereadurl://");
-
+    queryService.conf.unset(LensConfConstants.RESULT_FS_READ_URL);
   }
 
   // test with execute async post with result formatter, get query, get results
@@ -149,8 +149,9 @@ public class TestResultFormatting extends LensJerseyTest {
     conf.addProperty(LensConfConstants.QUERY_PERSISTENT_RESULT_INDRIVER, "true");
     testResultFormatter(conf, QueryStatus.Status.SUCCESSFUL, false, null);
 
-    conf.addProperty(LensConfConstants.RESULT_FS_READ_URL, "filereadurl://");
+    queryService.conf.set(LensConfConstants.RESULT_FS_READ_URL, "filereadurl://");
     testResultFormatter(conf, QueryStatus.Status.SUCCESSFUL, false, "filereadurl://");
+    queryService.conf.unset(LensConfConstants.RESULT_FS_READ_URL);
   }
 
   /**
@@ -262,4 +263,8 @@ public class TestResultFormatting extends LensJerseyTest {
     }
   }
 
+  @AfterTest
+  public void waitForPurge() throws InterruptedException {
+    waitForPurge(0, queryService.finishedQueries);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/lens-server/src/test/resources/lens-site.xml
----------------------------------------------------------------------
diff --git a/lens-server/src/test/resources/lens-site.xml b/lens-server/src/test/resources/lens-site.xml
index f728810..cc887ef 100644
--- a/lens-server/src/test/resources/lens-site.xml
+++ b/lens-server/src/test/resources/lens-site.xml
@@ -127,9 +127,9 @@
   </property>
 
   <property>
-    <!-- Keep only the last query in memory -->
-    <name>lens.server.max.finished.queries</name>
-    <value>1</value>
+    <!-- run every second -->
+    <name>lens.server.purge.interval</name>
+    <value>1000</value>
   </property>
 
   <property>

http://git-wip-us.apache.org/repos/asf/lens/blob/669e8727/src/site/apt/admin/config.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/admin/config.apt b/src/site/apt/admin/config.apt
index 3500441..3a0678f 100644
--- a/src/site/apt/admin/config.apt
+++ b/src/site/apt/admin/config.apt
@@ -101,43 +101,43 @@ Lens server configuration
 *--+--+---+--+
 |37|lens.server.mail.smtp.timeout|30000|Socket read timeout value in milliseconds. This timeout is implemented by java.net.Socket. Default is 30 seconds.|
 *--+--+---+--+
-|38|lens.server.max.finished.queries|100|Maximum number of finished queries which lens server will keep in memory before purging.|
+|38|lens.server.metastore.service.impl|org.apache.lens.server.metastore.CubeMetastoreServiceImpl|Implementation class for metastore service|
 *--+--+---+--+
-|39|lens.server.metastore.service.impl|org.apache.lens.server.metastore.CubeMetastoreServiceImpl|Implementation class for metastore service|
+|39|lens.server.metastore.ws.resource.impl|org.apache.lens.server.metastore.MetastoreResource|Implementation class for Metastore Resource|
 *--+--+---+--+
-|40|lens.server.metastore.ws.resource.impl|org.apache.lens.server.metastore.MetastoreResource|Implementation class for Metastore Resource|
+|40|lens.server.metrics.csv.directory.path|metrics/|Path of the directory in which to report metrics as separate csv files.|
 *--+--+---+--+
-|41|lens.server.metrics.csv.directory.path|metrics/|Path of the directory in which to report metrics as separate csv files.|
+|41|lens.server.metrics.ganglia.host| |The ganglia host name|
 *--+--+---+--+
-|42|lens.server.metrics.ganglia.host| |The ganglia host name|
+|42|lens.server.metrics.ganglia.port| |The ganglia port|
 *--+--+---+--+
-|43|lens.server.metrics.ganglia.port| |The ganglia port|
+|43|lens.server.metrics.graphite.host| |The graphite host name|
 *--+--+---+--+
-|44|lens.server.metrics.graphite.host| |The graphite host name|
+|44|lens.server.metrics.graphite.port| |The graphite port|
 *--+--+---+--+
-|45|lens.server.metrics.graphite.port| |The graphite port|
+|45|lens.server.metrics.reporting.period|10|The reporting period for metrics. The value is in seconds|
 *--+--+---+--+
-|46|lens.server.metrics.reporting.period|10|The reporting period for metrics. The value is in seconds|
+|46|lens.server.mode|OPEN|The mode in which server should run. Allowed values are OPEN, READ_ONLY, METASTORE_READONLY, METASTORE_NODROP. OPEN mode will allow all requests. READ_ONLY mode will allow all requests on session resouce and only GET requests on all other resources. METASTORE_READONLY will allow GET on metastore and all other requests in other services. METASTORE_NODROP will not allow DELETE on metastore, will allow all other requests.|
 *--+--+---+--+
-|47|lens.server.mode|OPEN|The mode in which server should run. Allowed values are OPEN, READ_ONLY, METASTORE_READONLY, METASTORE_NODROP. OPEN mode will allow all requests. READ_ONLY mode will allow all requests on session resouce and only GET requests on all other resources. METASTORE_READONLY will allow GET on metastore and all other requests in other services. METASTORE_NODROP will not allow DELETE on metastore, will allow all other requests.|
+|47|lens.server.multipart.ws.feature.impl|org.glassfish.jersey.media.multipart.MultiPartFeature|Implementation class for query scheduler resource|
 *--+--+---+--+
-|48|lens.server.multipart.ws.feature.impl|org.glassfish.jersey.media.multipart.MultiPartFeature|Implementation class for query scheduler resource|
+|48|lens.server.persist.location|file:///tmp/lensserver|The directory in which lens server will persist its state when it is going down. The location be on any Hadoop compatible file system. Server will read from the location when it is restarted and recovery is enabled. So, Server should have both read and write permissions to the location|
 *--+--+---+--+
-|49|lens.server.persist.location|file:///tmp/lensserver|The directory in which lens server will persist its state when it is going down. The location be on any Hadoop compatible file system. Server will read from the location when it is restarted and recovery is enabled. So, Server should have both read and write permissions to the location|
+|49|lens.server.query.acceptors| |Query Acceptors configured. Query acceptors are consulted first, before anything happens for the given query. They can either return null or return a messaging indicating why the given query shouldn't be accepted. These can be used to filter out queries at the earliest.|
 *--+--+---+--+
-|50|lens.server.query.acceptors| |Query Acceptors configured. Query acceptors are consulted first, before anything happens for the given query. They can either return null or return a messaging indicating why the given query shouldn't be accepted. These can be used to filter out queries at the earliest.|
+|50|lens.server.query.launching.constraint.factories|org.apache.lens.server.query.constraint.TotalQueryCostCeilingConstraintFactory|Factories used to instantiate constraints enforced on queries by lens. Every Factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint. A query will be launched only if all constraints pass.|
 *--+--+---+--+
-|51|lens.server.query.launching.constraint.factories|org.apache.lens.server.query.constraint.TotalQueryCostCeilingConstraintFactory|Factories used to instantiate constraints enforced on queries by lens. Every Factory should be an implementation of org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create an implementation of org.apache.lens.server.api.query.constraint.QueryLaunchingConstraint. A query will be launched only if all constraints pass.|
-*--+--+---+--+
-|52|lens.server.query.phase1.rewriters| |Query phase 1 rewriters. This is to convert user query to cube query. The resulting cube query will be passed for validation and rewriting to hql query.\ |
+|51|lens.server.query.phase1.rewriters| |Query phase 1 rewriters. This is to convert user query to cube query. The resulting cube query will be passed for validation and rewriting to hql query.\ |
 |  |                                  | |Use cases will be to use extra intelligence to convert user query to optimized cube query.                                                              \ |
 |  |                                  | |Or define shortcuts for certain frequently used queries :)                                                                                                |
 *--+--+---+--+
-|53|lens.server.query.service.impl|org.apache.lens.server.query.QueryExecutionServiceImpl|Implementation class for query execution service|
+|52|lens.server.query.service.impl|org.apache.lens.server.query.QueryExecutionServiceImpl|Implementation class for query execution service|
+*--+--+---+--+
+|53|lens.server.query.state.logger.enabled|true|Disable or enable the query state logger with this config. The location for the logger can be specified in logback xml for the class org.apache.lens.server.query.QueryExecutionServiceImpl.QueryStatusLogger|
 *--+--+---+--+
-|54|lens.server.query.state.logger.enabled|true|Disable or enable the query state logger with this config. The location for the logger can be specified in logback xml for the class org.apache.lens.server.query.QueryExecutionServiceImpl.QueryStatusLogger|
+|54|lens.server.query.ws.resource.impl|org.apache.lens.server.query.QueryServiceResource|Implementation class for Query Resource|
 *--+--+---+--+
-|55|lens.server.query.ws.resource.impl|org.apache.lens.server.query.QueryServiceResource|Implementation class for Query Resource|
+|55|lens.server.querypurger.sleep.interval|10000|The interval(milliseconds) with which purger to run periodically. Default 10 sec.|
 *--+--+---+--+
 |56|lens.server.quota.service.impl|org.apache.lens.server.quota.QuotaServiceImpl|Implementation class for quota service|
 *--+--+---+--+
@@ -167,7 +167,7 @@ Lens server configuration
 *--+--+---+--+
 |69|lens.server.service.provider.factory|org.apache.lens.server.ServiceProviderFactoryImpl|Service provider factory implementation class. This parameter is used to lookup the factory implementation class name that would provide an instance of ServiceProvider. Users should instantiate the class to obtain its instance. Example -- Class spfClass = conf.getClass("lens.server.service.provider.factory", null, ServiceProviderFactory.class); ServiceProviderFactory spf = spfClass.newInstance(); ServiceProvider serviceProvider = spf.getServiceProvider(); -- This is not supposed to be overridden by users.|
 *--+--+---+--+
-|70|lens.server.servicenames|session,query,metastore,scheduler,quota,savedquery|These services would be started in the specified order when lens-server starts up|
+|70|lens.server.servicenames|session,query,metastore,scheduler,quota|These services would be started in the specified order when lens-server starts up|
 *--+--+---+--+
 |71|lens.server.session.expiry.service.interval.secs|3600|Interval at which lens session expiry service runs|
 *--+--+---+--+
@@ -237,6 +237,6 @@ Lens server configuration
 *--+--+---+--+
 |104|lens.server.ws.listenernames|appevent|These listeners would be called in the specified order when lens-server starts up|
 *--+--+---+--+
-|105|lens.server.ws.resourcenames|session,metastore,query,quota,scheduler,index,log,savedquery|These JAX-RS resources would be started in the specified order when lens-server starts up|
+|105|lens.server.ws.resourcenames|session,metastore,query,quota,scheduler,index,log|These JAX-RS resources would be started in the specified order when lens-server starts up|
 *--+--+---+--+
 The configuration parameters and their default values


[24/50] [abbrv] lens git commit: LENS-744 : Fix sessionExpiryInterval constant

Posted by ra...@apache.org.
LENS-744 : Fix sessionExpiryInterval constant


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/3862c384
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/3862c384
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/3862c384

Branch: refs/heads/current-release-line
Commit: 3862c384feae254d8360e4f530e5f2666327c4f9
Parents: 7678a63
Author: Deepak Barr <de...@gmail.com>
Authored: Thu Sep 17 07:30:19 2015 +0530
Committer: raju.bairishetti <ra...@apache.org>
Committed: Thu Sep 17 07:30:19 2015 +0530

----------------------------------------------------------------------
 .../main/java/org/apache/lens/server/api/LensConfConstants.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/3862c384/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
----------------------------------------------------------------------
diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
index 90aea0b..096d26e 100644
--- a/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
+++ b/lens-server-api/src/main/java/org/apache/lens/server/api/LensConfConstants.java
@@ -731,7 +731,7 @@ public final class LensConfConstants {
    * Interval at which lens session expiry service runs
    */
   public static final String SESSION_EXPIRY_SERVICE_INTERVAL_IN_SECS = SERVER_PFX
-    + "session.expiry.serivce.interval.secs";
+    + "session.expiry.service.interval.secs";
 
   public static final int DEFAULT_SESSION_EXPIRY_SERVICE_INTERVAL_IN_SECS = 3600;
 


[22/50] [abbrv] lens git commit: LENS-756: Example query on customer_city_name failing

Posted by ra...@apache.org.
LENS-756: Example query on customer_city_name failing


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

Branch: refs/heads/current-release-line
Commit: c8701a38da380d771f40ae953b48221eb46aa2ee
Parents: 08135aa
Author: Amareshwari Sriramadasu <am...@gmail.com>
Authored: Wed Sep 16 17:22:23 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Wed Sep 16 17:22:23 2015 +0530

----------------------------------------------------------------------
 lens-examples/src/main/resources/sales-cube.xml | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/c8701a38/lens-examples/src/main/resources/sales-cube.xml
----------------------------------------------------------------------
diff --git a/lens-examples/src/main/resources/sales-cube.xml b/lens-examples/src/main/resources/sales-cube.xml
index 9cc2fe6..7ec2ec7 100644
--- a/lens-examples/src/main/resources/sales-cube.xml
+++ b/lens-examples/src/main/resources/sales-cube.xml
@@ -58,7 +58,6 @@
                    display_string="Customer City">
       <ref_spec>
         <chain_ref_column chain_name="customer_city" ref_col="name" />
-        <chain_ref_column chain_name="customer_details" ref_col="customer_city_name" />
       </ref_spec>
     </dim_attribute>
     <dim_attribute name="production_location">


[06/50] [abbrv] lens git commit: Merge with current-release-line

Posted by ra...@apache.org.
Merge with current-release-line


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/2901b4b3
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/2901b4b3
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/2901b4b3

Branch: refs/heads/current-release-line
Commit: 2901b4b33677f694b68adb22eee7994307bd77d4
Parents: fe44e69 1237842
Author: Rajat Khandelwal <ra...@gmail.com>
Authored: Fri Aug 28 20:15:16 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Fri Aug 28 20:15:16 2015 +0530

----------------------------------------------------------------------
 lens-driver-es/pom.xml                             |  3 +--
 .../src/test/resources/valid-queries.data          |  2 +-
 lens-driver-jdbc/pom.xml                           | 15 +++++++--------
 lens-server/pom.xml                                | 17 ++++++++---------
 pom.xml                                            |  5 ++---
 5 files changed, 19 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/2901b4b3/lens-driver-es/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/lens/blob/2901b4b3/lens-driver-es/src/test/resources/valid-queries.data
----------------------------------------------------------------------
diff --cc lens-driver-es/src/test/resources/valid-queries.data
index f4ad15b,46de030..ff3074e
--- a/lens-driver-es/src/test/resources/valid-queries.data
+++ b/lens-driver-es/src/test/resources/valid-queries.data
@@@ -82,20 -82,5 +82,20 @@@
      "name" : "Group by with multiple aggregation and complex criteria, select order jumbled",
      "hql" : "select count(col1), col2, max(col3) from index.type where !(col1=5 and col2='p' and col3='wer' or (col4='9')) group by col2",
      "expectedJson" : {"size":0,"timeout":10000,"aggs":{"filter_wrapper":{"aggs":{"col2":{"terms":{"field":"col2","size":100},"aggs":{"col1":{"value_count":{"field":"col1"}},"col3":{"max":{"field":"col3"}}}}},"filter":{"not":{"or":[{"and":[{"and":[{"term":{"col1":"5"}},{"term":{"col2":"p"}}]},{"term":{"col3":"wer"}}]},{"term":{"col4":"9"}}]}}}}}
 +  },
 +  {
 +    "name" : "Check in predicate",
 +    "hql" : "select col1 from index.type where col2 in ('val1', 'val2')",
 +    "expectedJson" : {"from":0,"size":10000,"fields":["col1"],"sort":[],"timeout":10000,"filter":{"terms":{"col2":["val1","val2"]}}}
 +  },
 +  {
 +    "name" : "Check not in predicate",
 +    "hql" : "select col1 from index.type where col2 not in ('val1', 'val2')",
 +    "expectedJson" : {"from":0,"size":10000,"fields":["col1"],"sort":[],"timeout":10000,"filter":{"not":{"terms":{"col2":["val1","val2"]}}}}
 +  },
 +  {
 +    "name" : "Check not equals predicate",
 +    "hql" : "select col1 from index.type where col2 != 'val1'",
 +    "expectedJson" : {"from":0,"size":10000,"fields":["col1"],"sort":[],"timeout":10000,"filter":{"not":{"term":{"col2":"val1"}}}}
    }
- ]
+ ]

http://git-wip-us.apache.org/repos/asf/lens/blob/2901b4b3/lens-driver-jdbc/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/lens/blob/2901b4b3/lens-server/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/lens/blob/2901b4b3/pom.xml
----------------------------------------------------------------------