You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2015/04/17 21:10:34 UTC

[5/5] ambari git commit: AMBARI-10528. Hive View: Visual Explain, Error handling and bugfixes (alexantonenko)

AMBARI-10528. Hive View: Visual Explain, Error handling and bugfixes (alexantonenko)


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

Branch: refs/heads/trunk
Commit: 672eee34dce8200f7375f164c307d864b4f5ffd1
Parents: 2917d0d
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Apr 17 18:39:50 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Fri Apr 17 22:10:24 2015 +0300

----------------------------------------------------------------------
 contrib/views/hive/pom.xml                      |  11 +-
 .../ambari/view/hive/PropertyValidator.java     | 109 +++++
 .../ambari/view/hive/client/Connection.java     |  44 +-
 .../view/hive/client/ConnectionFactory.java     |   7 +-
 .../apache/ambari/view/hive/client/Cursor.java  |  22 +-
 .../ambari/view/hive/client/DDLDelegator.java   |   2 +-
 .../hive/client/HiveErrorStatusException.java   |   2 +-
 .../apache/ambari/view/hive/client/Utils.java   |   2 +-
 .../view/hive/persistence/DataStoreStorage.java | 114 +++---
 .../persistence/InstanceKeyValueStorage.java    |   5 -
 .../hive/persistence/LocalKeyValueStorage.java  |   5 -
 .../ambari/view/hive/persistence/Storage.java   |   9 -
 .../hive/resources/CRUDResourceManager.java     |   2 +-
 .../view/hive/resources/files/FileService.java  |  36 +-
 .../view/hive/resources/jobs/Aggregator.java    |   3 +-
 .../resources/jobs/ConnectionController.java    |  15 +-
 .../view/hive/resources/jobs/JobService.java    |  74 +++-
 .../jobs/NoOperationStatusSetException.java     |   5 +-
 .../jobs/OperationHandleController.java         |  45 ++-
 .../jobs/OperationHandleResourceManager.java    |   2 +-
 .../jobs/ResultsPaginationController.java       |  24 ++
 .../resources/jobs/StoredOperationHandle.java   |   2 +-
 .../hive/resources/jobs/atsJobs/ATSParser.java  |   1 +
 .../jobs/atsJobs/ATSRequestsDelegate.java       |   8 +
 .../jobs/atsJobs/ATSRequestsDelegateImpl.java   |  24 +-
 .../resources/jobs/atsJobs/HiveQueryId.java     |   2 +
 .../view/hive/resources/jobs/viewJobs/Job.java  |   8 +
 .../resources/jobs/viewJobs/JobController.java  |   1 +
 .../jobs/viewJobs/JobControllerImpl.java        |  39 +-
 .../hive/resources/jobs/viewJobs/JobImpl.java   |  28 +-
 .../ambari/view/hive/resources/udfs/UDF.java    |   6 +-
 .../apache/ambari/view/hive/utils/HdfsApi.java  |   6 +-
 .../apache/ambari/view/hive/utils/HdfsUtil.java |   8 +-
 .../utils/HiveClientFormattedException.java     |  26 ++
 .../src/main/resources/ui/hive-web/.bowerrc     |   4 +
 .../main/resources/ui/hive-web/.editorconfig    |  34 ++
 .../src/main/resources/ui/hive-web/.ember-cli   |  27 ++
 .../src/main/resources/ui/hive-web/.travis.yml  |  38 ++
 .../src/main/resources/ui/hive-web/Brocfile.js  |   5 +
 .../app/components/alert-message-widget.js      |  16 +-
 .../app/components/collapsible-widget.js        |   5 +
 .../ui/hive-web/app/components/modal-widget.js  |  22 +
 .../ui/hive-web/app/components/notify-widget.js |  32 ++
 .../app/components/number-range-widget.js       |  36 +-
 .../ui/hive-web/app/components/query-tabs.js    | 121 ++++++
 .../hive-web/app/components/typeahead-widget.js |  49 ++-
 .../ui/hive-web/app/controllers/alerts.js       |  47 ---
 .../ui/hive-web/app/controllers/databases.js    |  56 ++-
 .../ui/hive-web/app/controllers/index.js        | 188 +++++++--
 .../controllers/index/history-query/explain.js  |  36 +-
 .../app/controllers/index/history-query/logs.js |  22 +-
 .../controllers/index/history-query/results.js  |  34 ++
 .../ui/hive-web/app/controllers/messages.js     |  33 ++
 .../app/controllers/modal-save-query.js         |  42 ++
 .../ui/hive-web/app/controllers/open-queries.js | 120 ++++--
 .../ui/hive-web/app/controllers/queries.js      |  11 +-
 .../ui/hive-web/app/controllers/settings.js     |  63 ++-
 .../ui/hive-web/app/controllers/udf.js          |   4 +-
 .../ui/hive-web/app/helpers/all-uppercase.js    |   2 +-
 .../hive-web/app/helpers/preformatted-string.js |  28 ++
 .../main/resources/ui/hive-web/app/index.html   |   4 +
 .../ui/hive-web/app/initializers/i18n.js        |  43 +-
 .../ui/hive-web/app/initializers/notify.js      |  26 ++
 .../resources/ui/hive-web/app/models/file.js    |   2 +-
 .../resources/ui/hive-web/app/models/job.js     |   5 +
 .../ui/hive-web/app/routes/application.js       |  17 +-
 .../ui/hive-web/app/routes/index/index.js       |   4 +-
 .../ui/hive-web/app/services/notify.js          |  88 ++++
 .../resources/ui/hive-web/app/styles/app.scss   | 136 +++++--
 .../ui/hive-web/app/styles/mixins.scss          |  23 ++
 .../ui/hive-web/app/styles/notifications.scss   |  36 ++
 .../ui/hive-web/app/styles/query-tabs.scss      |  68 ++++
 .../resources/ui/hive-web/app/styles/vars.scss  |  20 +
 .../ui/hive-web/app/templates/alerts.hbs        |  23 --
 .../ui/hive-web/app/templates/application.hbs   |   3 +-
 .../components/alert-message-widget.hbs         |   4 +-
 .../templates/components/collapsible-widget.hbs |   7 +-
 .../app/templates/components/notify-widget.hbs  |  21 +
 .../app/templates/components/panel-widget.hbs   |  12 +-
 .../app/templates/components/query-tabs.hbs     |  29 ++
 .../app/templates/components/tabs-widget.hbs    |   3 +-
 .../app/templates/databases-search-results.hbs  |   4 +-
 .../hive-web/app/templates/databases-tree.hbs   |   6 +-
 .../ui/hive-web/app/templates/databases.hbs     |   4 +-
 .../ui/hive-web/app/templates/index.hbs         |  24 +-
 .../templates/index/history-query/results.hbs   |   6 +-
 .../ui/hive-web/app/templates/insert-udfs.hbs   |  54 +--
 .../ui/hive-web/app/templates/message.hbs       |  36 ++
 .../ui/hive-web/app/templates/messages.hbs      |  30 ++
 .../ui/hive-web/app/templates/modal-delete.hbs  |   2 +-
 .../hive-web/app/templates/modal-save-query.hbs |  24 ++
 .../ui/hive-web/app/templates/notification.hbs  |  23 ++
 .../ui/hive-web/app/templates/open-queries.hbs  |   2 +-
 .../ui/hive-web/app/templates/settings.hbs      |  79 ++--
 .../ui/hive-web/app/templates/tez-ui.hbs        |   2 +
 .../hive-web/app/templates/visual-explain.hbs   |  58 +++
 .../ui/hive-web/app/utils/constants.js          |  23 +-
 .../ui/hive-web/app/utils/dag-rules.js          | 141 +++++++
 .../resources/ui/hive-web/app/views/message.js  |  36 ++
 .../ui/hive-web/app/views/notification.js       |  51 +++
 .../ui/hive-web/app/views/visual-explain.js     | 401 +++++++++++++++++++
 .../src/main/resources/ui/hive-web/bower.json   |  18 +-
 .../src/main/resources/ui/hive-web/package.json |  16 +-
 .../src/main/resources/ui/hive-web/testem.json  |   2 +-
 .../ui/hive-web/tests/helpers/api-mock.js       |   2 +-
 .../main/resources/ui/hive-web/tests/index.html |   6 +
 .../hive-web/tests/integration/database-test.js |   6 +-
 .../resources/ui/hive-web/tests/test-helper.js  |   6 -
 .../components/alert-message-widget-test.js     |  10 +-
 .../tests/unit/controllers/index-test.js        |  19 +-
 .../tests/unit/controllers/queries-test.js      |   5 +-
 .../tests/unit/controllers/settings-test.js     |  17 +-
 .../tests/unit/controllers/tez-ui-test.js       |   2 +-
 .../resources/ui/hive-web/vendor/dagre.min.js   |  27 ++
 contrib/views/hive/src/main/resources/view.xml  |   8 +-
 .../view/hive/resources/jobs/ATSParserTest.java |  22 +-
 .../hive/resources/jobs/AggregatorTest.java     |   2 +-
 pom.xml                                         |   1 +
 118 files changed, 2938 insertions(+), 583 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/hive/pom.xml b/contrib/views/hive/pom.xml
index e381719..81bf144 100644
--- a/contrib/views/hive/pom.xml
+++ b/contrib/views/hive/pom.xml
@@ -19,7 +19,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.ambari.contrib.views</groupId>
   <artifactId>hive</artifactId>
-  <version>0.1.0-SNAPSHOT</version>
+  <version>0.2.0-SNAPSHOT</version>
   <name>Hive</name>
 
   <parent>
@@ -30,6 +30,11 @@
 
   <dependencies>
     <dependency>
+      <groupId>com.jayway.jsonpath</groupId>
+      <artifactId>json-path</artifactId>
+      <version>2.0.0</version>
+    </dependency>
+      <dependency>
       <groupId>com.google.inject</groupId>
       <artifactId>guice</artifactId>
     </dependency>
@@ -195,8 +200,8 @@
         <artifactId>frontend-maven-plugin</artifactId>
         <version>0.0.14</version>
         <configuration>
-          <nodeVersion>v0.10.32</nodeVersion>
-          <npmVersion>1.4.3</npmVersion>
+          <nodeVersion>v0.12.2</nodeVersion>
+          <npmVersion>1.4.8</npmVersion>
           <workingDirectory>src/main/resources/ui/hive-web/</workingDirectory>
         </configuration>
         <executions>

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/PropertyValidator.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/PropertyValidator.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/PropertyValidator.java
new file mode 100644
index 0000000..61efa49
--- /dev/null
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/PropertyValidator.java
@@ -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.
+ */
+
+package org.apache.ambari.view.hive;
+
+import org.apache.ambari.view.ViewInstanceDefinition;
+import org.apache.ambari.view.validation.ValidationResult;
+import org.apache.ambari.view.validation.Validator;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class PropertyValidator implements Validator {
+
+  public static final String WEBHDFS_URL = "webhdfs.url";
+  public static final String HIVE_PORT = "hive.port";
+  public static final String YARN_ATS_URL = "yarn.ats.url";
+  public static final String HIVE_AUTH = "hive.auth";
+
+  @Override
+  public ValidationResult validateInstance(ViewInstanceDefinition viewInstanceDefinition, ValidationContext validationContext) {
+    return null;
+  }
+
+  @Override
+  public ValidationResult validateProperty(String property, ViewInstanceDefinition viewInstanceDefinition, ValidationContext validationContext) {
+    if (property.equals(WEBHDFS_URL)) {
+      String webhdfsUrl = viewInstanceDefinition.getPropertyMap().get(WEBHDFS_URL);
+      if (validateURL(webhdfsUrl)) return new InvalidPropertyValidationResult(false, "Must be valid URL");
+    }
+
+    if (property.equals(HIVE_PORT)) {
+      String hivePort = viewInstanceDefinition.getPropertyMap().get(HIVE_PORT);
+      try {
+        int port = Integer.valueOf(hivePort);
+        if (port < 1 || port > 65535) {
+          return new InvalidPropertyValidationResult(false, "Must be from 1 to 65535");
+        }
+      } catch (NumberFormatException e) {
+        return new InvalidPropertyValidationResult(false, "Must be integer");
+      }
+    }
+
+    if (property.equals(YARN_ATS_URL)) {
+      String atsUrl = viewInstanceDefinition.getPropertyMap().get(YARN_ATS_URL);
+      if (validateURL(atsUrl)) return new InvalidPropertyValidationResult(false, "Must be valid URL");
+    }
+
+    if (property.equals(HIVE_AUTH)) {
+      String auth = viewInstanceDefinition.getPropertyMap().get(HIVE_AUTH);
+
+      if (auth != null && !auth.isEmpty()) {
+        for(String param : auth.split(";")) {
+          String[] keyvalue = param.split("=");
+          if (keyvalue.length != 2) {
+            return new InvalidPropertyValidationResult(false, "Can not parse authentication param " + param + " in " + auth);
+          }
+        }
+      }
+    }
+
+    return ValidationResult.SUCCESS;
+  }
+
+  public boolean validateURL(String webhdfsUrl) {
+    try {
+      new URI(webhdfsUrl);
+    } catch (URISyntaxException e) {
+      return true;
+    }
+    return false;
+  }
+
+  public static class InvalidPropertyValidationResult implements ValidationResult {
+    private boolean valid;
+    private String detail;
+
+    public InvalidPropertyValidationResult(boolean valid, String detail) {
+      this.valid = valid;
+      this.detail = detail;
+    }
+
+    @Override
+    public boolean isValid() {
+      return valid;
+    }
+
+    @Override
+    public String getDetail() {
+      return detail;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Connection.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Connection.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Connection.java
index 70b5047..cf1a998 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Connection.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Connection.java
@@ -82,7 +82,7 @@ public class Connection {
       transport.open();
       client = new TCLIService.Client(new TBinaryProtocol(transport));
     } catch (TTransportException e) {
-      throw new HiveClientException("Could not establish connecton to "
+      throw new HiveClientException("H020 Could not establish connecton to "
           + host + ":" + port + ": " + e.toString(), e);
     }
     LOG.info("Hive connection opened");
@@ -109,7 +109,7 @@ public class Connection {
             try {
               saslQOP = SaslQOP.fromString(authParams.get(Utils.HiveAuthenticationParams.AUTH_QOP));
             } catch (IllegalArgumentException e) {
-              throw new HiveClientException("Invalid " + Utils.HiveAuthenticationParams.AUTH_QOP +
+              throw new HiveClientException("H040 Invalid " + Utils.HiveAuthenticationParams.AUTH_QOP +
                   " parameter. " + e.getMessage(), e);
             }
           }
@@ -162,7 +162,7 @@ public class Connection {
         return HiveAuthFactory.getSocketTransport(host, port, 10000);
       }
     } catch (SaslException e) {
-      throw new HiveClientException("Could not create secure connection to "
+      throw new HiveClientException("H040 Could not create secure connection to "
           + host + ": " + e.getMessage(), e);
     }
     return transport;
@@ -181,7 +181,7 @@ public class Connection {
         tokenStr = ShimLoader.getHadoopShims().
             getTokenStrForm(HiveAuthFactory.HS2_CLIENT_TOKEN);
       } catch (IOException e) {
-        throw new HiveClientException("Error reading token ", e);
+        throw new HiveClientException("H050 Error reading token", e);
       }
     }
     return tokenStr;
@@ -205,12 +205,12 @@ public class Connection {
         try {
           return client.OpenSession(openReq);
         } catch (TException e) {
-          throw new HiveClientException("Unable to open Hive session", e);
+          throw new HiveClientException("H060 Unable to open Hive session", e);
         }
 
       }
     }.call();
-    Utils.verifySuccess(openResp.getStatus(), "Unable to open Hive session");
+    Utils.verifySuccess(openResp.getStatus(), "H070 Unable to open Hive session");
 
     if (protocol == null)
       protocol = openResp.getServerProtocolVersion();
@@ -231,7 +231,7 @@ public class Connection {
   public TSessionHandle getSessionByTag(String tag) throws HiveClientException {
     TSessionHandle sessionHandle = sessHandles.get(tag);
     if (sessionHandle == null) {
-      throw new HiveClientException("Session with provided tag not found", null);
+      throw new HiveClientException("E030 Session with provided tag not found", null);
     }
     return sessionHandle;
   }
@@ -244,15 +244,21 @@ public class Connection {
     }
   }
 
+  public void invalidateSessionByTag(String tag) throws HiveClientException {
+    TSessionHandle sessionHandle = getSessionByTag(tag);
+    closeSession(sessionHandle);
+    sessHandles.remove(tag);
+  }
+
   private synchronized void closeSession(TSessionHandle sessHandle) throws HiveClientException {
     if (sessHandle == null) return;
     TCloseSessionReq closeReq = new TCloseSessionReq(sessHandle);
     TCloseSessionResp closeResp = null;
     try {
       closeResp = client.CloseSession(closeReq);
-      Utils.verifySuccess(closeResp.getStatus(), "Unable to close Hive session");
+      Utils.verifySuccess(closeResp.getStatus(), "H080 Unable to close Hive session");
     } catch (TException e) {
-      throw new HiveClientException("Unable to close Hive session", e);
+      throw new HiveClientException("H090 Unable to close Hive session", e);
     }
     LOG.info("Hive session closed");
   }
@@ -314,18 +320,18 @@ public class Connection {
           try {
             return client.ExecuteStatement(execReq);
           } catch (TException e) {
-            throw new HiveClientException("Unable to submit statement " + cmd, e);
+            throw new HiveClientException("H100 Unable to submit statement " + cmd, e);
           }
 
         }
       }.call();
 
-      Utils.verifySuccess(execResp.getStatus(), "Unable to submit statement " + cmd);
+      Utils.verifySuccess(execResp.getStatus(), "H110 Unable to submit statement");
       //TODO: check if status have results
       handle = execResp.getOperationHandle();
     }
     if (handle == null) {
-      throw new HiveClientException("Empty command given", null);
+      throw new HiveClientException("H120 Empty command given", null);
     }
     return handle;
   }
@@ -373,19 +379,11 @@ public class Connection {
         try {
           return client.GetOperationStatus(statusReq);
         } catch (TException e) {
-          throw new HiveClientException("Unable to fetch operation status", e);
+          throw new HiveClientException("H130 Unable to fetch operation status", e);
         }
 
       }
     }.call();
-//    transportLock.lock();
-//    try {
-//      return client.GetOperationStatus(statusReq);
-//    } catch (TException e) {
-//      throw new HiveClientException("Unable to fetch operation status", e);
-//    } finally {
-//      transportLock.unlock();
-//    }
   }
 
   /**
@@ -400,11 +398,11 @@ public class Connection {
         try {
           return client.CancelOperation(cancelReq);
         } catch (TException e) {
-          throw new HiveClientException("Unable to cancel operation", null);
+          throw new HiveClientException("H140 Unable to cancel operation", null);
         }
       }
     }.call();
-    Utils.verifySuccess(cancelResp.getStatus(), "Unable to cancel operation");
+    Utils.verifySuccess(cancelResp.getStatus(), "H150 Unable to cancel operation");
   }
 
   public int getPort() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java
index 6886f57..98256eb 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java
@@ -19,6 +19,7 @@
 package org.apache.ambari.view.hive.client;
 
 import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.hive.utils.HiveClientFormattedException;
 import org.apache.ambari.view.hive.utils.ServiceFormattedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,7 +42,7 @@ public class ConnectionFactory implements IConnectionFactory {
       return new Connection(getHiveHost(), Integer.valueOf(getHivePort()),
           getHiveAuthParams(), context.getUsername());
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException("Couldn't open connection to Hive: " + e.toString(), e);
+      throw new HiveClientFormattedException(e);
     }
   }
 
@@ -62,8 +63,8 @@ public class ConnectionFactory implements IConnectionFactory {
     for(String param : auth.split(";")) {
       String[] keyvalue = param.split("=");
       if (keyvalue.length != 2) {
-        LOG.error("Can not parse authentication param " + param + " in " + auth);
-        continue;
+        //Should never happen because validator already checked this
+        throw new ServiceFormattedException("H010 Can not parse authentication param " + param + " in " + auth);
       }
       params.put(keyvalue[0], keyvalue[1]);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Cursor.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Cursor.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Cursor.java
index 84987f5..16fdf36 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Cursor.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Cursor.java
@@ -21,6 +21,7 @@ package org.apache.ambari.view.hive.client;
 import static org.apache.hive.service.cli.thrift.TCLIServiceConstants.TYPE_NAMES;
 
 import org.apache.ambari.view.hive.utils.BadRequestFormattedException;
+import org.apache.ambari.view.hive.utils.HiveClientFormattedException;
 import org.apache.hive.service.cli.RowSet;
 import org.apache.hive.service.cli.RowSetFactory;
 import org.apache.hive.service.cli.thrift.*;
@@ -73,12 +74,12 @@ public class Cursor implements Iterator<Row>, Iterable<Row> {
         try {
           return client.FetchResults(fetchReq);
         } catch (TException e) {
-          throw new HiveClientException("Unable to fetch results", e);
+          throw new HiveClientException("H160 Unable to fetch results", e);
         }
 
       }
     }.call();
-    Utils.verifySuccess(fetchResp.getStatus(), "Unable to fetch results");
+    Utils.verifySuccess(fetchResp.getStatus(), "H170 Unable to fetch results");
     TRowSet results = fetchResp.getResults();
     fetched = RowSetFactory.create(results, connection.getProtocol());
     fetchedIterator = fetched.iterator();
@@ -90,7 +91,6 @@ public class Cursor implements Iterator<Row>, Iterable<Row> {
 
   public ArrayList<ColumnDescription> getSchema() throws HiveClientException {
     if (this.schema == null) {
-      // TODO: extract all HiveCall inline classes to separate files
       TGetResultSetMetadataResp fetchResp = new HiveCall<TGetResultSetMetadataResp>(connection) {
         @Override
         public TGetResultSetMetadataResp body() throws HiveClientException {
@@ -99,12 +99,12 @@ public class Cursor implements Iterator<Row>, Iterable<Row> {
           try {
             return client.GetResultSetMetadata(fetchReq);
           } catch (TException e) {
-            throw new HiveClientException("Unable to fetch results metadata", e);
+            throw new HiveClientException("H180 Unable to fetch results metadata", e);
           }
 
         }
       }.call();
-      Utils.verifySuccess(fetchResp.getStatus(), "Unable to fetch results metadata");
+      Utils.verifySuccess(fetchResp.getStatus(), "H190 Unable to fetch results metadata");
       TTableSchema schema = fetchResp.getSchema();
 
       List<TColumnDesc> thriftColumns = schema.getColumns();
@@ -168,7 +168,7 @@ public class Cursor implements Iterator<Row>, Iterable<Row> {
       try {
         fetchNextBlock();
       } catch (HiveClientException e) {
-        throw new HiveClientRuntimeException(e.getMessage(), e);
+        throw new HiveClientFormattedException(e);
       }
     }
   }
@@ -209,6 +209,16 @@ public class Cursor implements Iterator<Row>, Iterable<Row> {
     return read;
   }
 
+  public Row getHeadersRow() throws HiveClientException {
+    ArrayList<ColumnDescription> schema = getSchema();
+
+    Object[] row = new Object[schema.size()];
+    for (ColumnDescription columnDescription : schema) {
+      row[columnDescription.getPosition()-1] = columnDescription.getName();
+    }
+    return new Row(row, selectedColumns);
+  }
+
   public int readRaw(ArrayList<Object[]> rows, int count) {
     int read = 0;
     while(read < count && hasNext()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/DDLDelegator.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/DDLDelegator.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/DDLDelegator.java
index 8326e50..eda12ed 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/DDLDelegator.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/DDLDelegator.java
@@ -129,7 +129,7 @@ public class DDLDelegator {
         try {
           return connection.getClient().GetColumns(req);
         } catch (TException e) {
-          throw new HiveClientException("Unable to get table columns", e);
+          throw new HiveClientException("H200 Unable to get table columns", e);
         }
       }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/HiveErrorStatusException.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/HiveErrorStatusException.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/HiveErrorStatusException.java
index 7adbe23..1b306dc 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/HiveErrorStatusException.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/HiveErrorStatusException.java
@@ -25,6 +25,6 @@ import org.apache.hive.service.cli.thrift.TStatusCode;
  */
 public class HiveErrorStatusException extends HiveClientException {
   public HiveErrorStatusException(TStatusCode statusCode, String comment) {
-    super(String.format("Failed with status %s: %s", statusCode, comment), null);
+    super(String.format("%s [%s]", comment, statusCode), null);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Utils.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Utils.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Utils.java
index fd1ecb5..e0dd438 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Utils.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/Utils.java
@@ -26,7 +26,7 @@ public class Utils {
     if (status.getStatusCode() != TStatusCode.SUCCESS_STATUS &&
         status.getStatusCode() != TStatusCode.SUCCESS_WITH_INFO_STATUS) {
       String message = (status.getErrorMessage() != null) ? status.getErrorMessage() : "";
-      throw new HiveErrorStatusException(status.getStatusCode(), message + ": " + comment);
+      throw new HiveErrorStatusException(status.getStatusCode(), comment + ". " + message);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/DataStoreStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/DataStoreStorage.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/DataStoreStorage.java
index b4bc415..1e8f07f 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/DataStoreStorage.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/DataStoreStorage.java
@@ -25,10 +25,14 @@ import org.apache.ambari.view.hive.persistence.utils.Indexed;
 import org.apache.ambari.view.hive.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.hive.persistence.utils.OnlyOwnersFilteringStrategy;
 import org.apache.ambari.view.hive.utils.ServiceFormattedException;
+import org.apache.commons.beanutils.BeanUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.WebApplicationException;
+import java.beans.Transient;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -52,14 +56,52 @@ public class DataStoreStorage implements Storage {
 
   @Override
   public synchronized void store(Class model, Indexed obj) {
+    assignId(model, obj);
+
+    Indexed newBean;
     try {
-      if (obj.getId() == null) {
-        String id = nextIdForEntity(context, model);
-        obj.setId(id);
-      }
-      context.getDataStore().store(obj);
+      newBean = (Indexed) BeanUtils.cloneBean(obj);
+    } catch (IllegalAccessException e) {
+      throw new ServiceFormattedException("S010 Data storage error", e);
+    } catch (InstantiationException e) {
+      throw new ServiceFormattedException("S010 Data storage error", e);
+    } catch (InvocationTargetException e) {
+      throw new ServiceFormattedException("S010 Data storage error", e);
+    } catch (NoSuchMethodException e) {
+      throw new ServiceFormattedException("S010 Data storage error", e);
+    }
+    preprocessEntity(newBean);
+
+    try {
+      context.getDataStore().store(newBean);
     } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while saving object to DataStorage", e);
+      throw new ServiceFormattedException("S020 Data storage error", e);
+    }
+  }
+
+  public void assignId(Class model, Indexed obj) {
+    if (obj.getId() == null) {
+      String id = nextIdForEntity(context, model);
+      obj.setId(id);
+    }
+  }
+
+  private void preprocessEntity(Indexed obj) {
+    cleanTransientFields(obj);
+  }
+
+  private void cleanTransientFields(Indexed obj) {
+    for (Method m : obj.getClass().getMethods()) {
+      Transient aTransient = m.getAnnotation(Transient.class);
+      if (aTransient != null && m.getName().startsWith("set")) {
+        try {
+          m.invoke(obj, new Object[]{ null });
+        } catch (IllegalAccessException e) {
+          throw new ServiceFormattedException("S030 Data storage error", e);
+        } catch (InvocationTargetException e) {
+          throw new ServiceFormattedException("S030 Data storage error", e);
+        }
+      }
     }
   }
 
@@ -87,7 +129,7 @@ public class DataStoreStorage implements Storage {
         throw new ItemNotFound();
       }
     } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while finding object in DataStorage", e);
+      throw new ServiceFormattedException("S040 Data storage error", e);
     }
   }
 
@@ -96,27 +138,16 @@ public class DataStoreStorage implements Storage {
     LinkedList<T> list = new LinkedList<T>();
     LOG.debug(String.format("Loading all %s-s", model.getName()));
     try {
-      //TODO: use WHERE statement instead of this ugly filter
       for(T item: context.getDataStore().findAll(model, filter.whereStatement())) {
         list.add(item);
       }
     } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while finding all objects in DataStorage", e);
+      throw new ServiceFormattedException("S050 Data storage error", e);
     }
     return list;
   }
 
   @Override
-  public <T extends Indexed> List<T> loadWhere(Class<T> model, String where) {
-    LOG.debug(String.format("Loading all %s-s", model.getName()));
-    try {
-      return new ArrayList<T>(context.getDataStore().findAll(model, where));
-    } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while finding objects in DataStorage; where = " + where, e);
-    }
-  }
-
-  @Override
   public synchronized <T extends Indexed> List<T> loadAll(Class<T> model) {
     return loadAll(model, new OnlyOwnersFilteringStrategy(this.context.getUsername()));
   }
@@ -128,7 +159,7 @@ public class DataStoreStorage implements Storage {
     try {
       context.getDataStore().remove(obj);
     } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while removing object from DataStorage", e);
+      throw new ServiceFormattedException("S060 Data storage error", e);
     }
   }
 
@@ -137,48 +168,7 @@ public class DataStoreStorage implements Storage {
     try {
       return context.getDataStore().find(model, id) != null;
     } catch (PersistenceException e) {
-      throw new ServiceFormattedException("Error while finding object in DataStorage", e);
-    }
-  }
-
-  public static void storageSmokeTest(ViewContext context) {
-    try {
-      SmokeTestEntity entity = new SmokeTestEntity();
-      entity.setData("42");
-      DataStoreStorage storage = new DataStoreStorage(context);
-      storage.store(SmokeTestEntity.class, entity);
-
-      if (entity.getId() == null) throw new ServiceFormattedException("Ambari Views instance data DB doesn't work properly (auto increment id doesn't work)", null);
-      Object id = entity.getId();
-      SmokeTestEntity entity2 = storage.load(SmokeTestEntity.class, id);
-      boolean status = entity2.getData().compareTo("42") == 0;
-      storage.delete(SmokeTestEntity.class, id);
-      if (!status) throw new ServiceFormattedException("Ambari Views instance data DB doesn't work properly", null);
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
-
-  public static class SmokeTestEntity implements Indexed {
-    private String id = null;
-    private String data = null;
-
-    public String getId() {
-      return id;
-    }
-
-    public void setId(String id) {
-      this.id = id;
-    }
-
-    public String getData() {
-      return data;
-    }
-
-    public void setData(String data) {
-      this.data = data;
+      throw new ServiceFormattedException("S070 Data storage error", e);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/InstanceKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/InstanceKeyValueStorage.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/InstanceKeyValueStorage.java
index 932b58e..98703fa 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/InstanceKeyValueStorage.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/InstanceKeyValueStorage.java
@@ -132,9 +132,4 @@ public class InstanceKeyValueStorage extends KeyValueStorage {
       throw new ServiceFormattedException(ex.getMessage(), ex);
     }
   }
-
-  @Override
-  public <T extends Indexed> List<T> loadWhere(Class<T> model, String where) {
-    throw new NotImplementedException();
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/LocalKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/LocalKeyValueStorage.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/LocalKeyValueStorage.java
index 674029a..24ed335 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/LocalKeyValueStorage.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/LocalKeyValueStorage.java
@@ -70,9 +70,4 @@ public class LocalKeyValueStorage extends KeyValueStorage {
     }
     return config;
   }
-
-  @Override
-  public <T extends Indexed> List<T> loadWhere(Class<T> model, String where) {
-    throw new NotImplementedException();
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/Storage.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/Storage.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/Storage.java
index 188282e..a34f566 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/Storage.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/persistence/Storage.java
@@ -55,15 +55,6 @@ public interface Storage {
   /**
    * Load all objects of given bean class
    * @param model bean class
-   * @param where filtering strategy (where clause)
-   * @param <T> bean class
-   * @return list of filtered objects
-   */
-  <T extends Indexed> List<T> loadWhere(Class<T> model, String where);
-
-  /**
-   * Load all objects of given bean class
-   * @param model bean class
    * @param <T> bean class
    * @return list of all objects
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/CRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/CRUDResourceManager.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/CRUDResourceManager.java
index 891b526..c7167a8 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/CRUDResourceManager.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/CRUDResourceManager.java
@@ -124,7 +124,7 @@ abstract public class CRUDResourceManager<T extends Indexed> implements IResourc
     try {
       delete(object.getId());
     } catch (ItemNotFound itemNotFound) {
-      throw new ServiceFormattedException("Error in creation, during clean up: " + itemNotFound.toString(), itemNotFound);
+      throw new ServiceFormattedException("E040 Item not found", itemNotFound);
     }
     throw e;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/files/FileService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/files/FileService.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/files/FileService.java
index 3f5b3b8..8bde44c 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/files/FileService.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/files/FileService.java
@@ -19,11 +19,13 @@
 package org.apache.ambari.view.hive.resources.files;
 
 import com.google.inject.Inject;
+import com.jayway.jsonpath.JsonPath;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewResourceHandler;
 import org.apache.ambari.view.hive.BaseService;
 import org.apache.ambari.view.hive.utils.*;
 import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileAlreadyExistsException;
 import org.json.simple.JSONObject;
@@ -38,6 +40,9 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
 
 /**
  * File access resource
@@ -53,6 +58,7 @@ import java.io.IOException;
  */
 public class FileService extends BaseService {
   public static final String FAKE_FILE = "fakefile://";
+  public static final String JSON_PATH_FILE = "jsonpath:";
 
   @Inject
   ViewResourceHandler handler;
@@ -78,10 +84,17 @@ public class FileService extends BaseService {
         if (page > 1)
           throw new IllegalArgumentException("There's only one page in fake files");
 
-        String content = filePath.substring(FAKE_FILE.length());
+        String encodedContent = filePath.substring(FAKE_FILE.length());
+        String content = new String(Base64.decodeBase64(encodedContent));
 
         fillFakeFileObject(filePath, file, content);
-      } else {
+      } else if (filePath.startsWith(JSON_PATH_FILE)) {
+        if (page > 1)
+          throw new IllegalArgumentException("There's only one page in fake files");
+
+        String content = getJsonPathContentByUrl(filePath);
+        fillFakeFileObject(filePath, file, content);
+      } else  {
         FilePaginator paginator = new FilePaginator(filePath, getSharedObjectsFactory().getHdfsApi());
 
         fillRealFileObject(filePath, page, file, paginator);
@@ -101,6 +114,19 @@ public class FileService extends BaseService {
     }
   }
 
+  protected String getJsonPathContentByUrl(String filePath) throws IOException {
+    URL url = new URL(filePath.substring(JSON_PATH_FILE.length()));
+
+    InputStream responseInputStream = context.getURLStreamProvider().readFrom(url.toString(), "GET",
+        null, new HashMap<String, String>());
+    String response = IOUtils.toString(responseInputStream);
+
+    for (String ref : url.getRef().split("!")) {
+      response = JsonPath.read(response, ref);
+    }
+    return response;
+  }
+
   public void fillRealFileObject(String filePath, Long page, FileResource file, FilePaginator paginator) throws IOException, InterruptedException {
     file.setFilePath(filePath);
     file.setFileContent(paginator.readPage(page));
@@ -109,9 +135,7 @@ public class FileService extends BaseService {
     file.setPageCount(paginator.pageCount());
   }
 
-  public void fillFakeFileObject(String filePath, FileResource file, String encodedContent) {
-    String content = new String(Base64.decodeBase64(encodedContent));
-
+  public void fillFakeFileObject(String filePath, FileResource file, String content) {
     file.setFilePath(filePath);
     file.setFileContent(content);
     file.setHasNext(false);
@@ -176,7 +200,7 @@ public class FileService extends BaseService {
         }
         output.close();
       } catch (FileAlreadyExistsException ex) {
-        throw new ServiceFormattedException(ex.getMessage(), ex, 400);
+        throw new ServiceFormattedException("F020 File already exists", ex, 400);
       }
       response.setHeader("Location",
           String.format("%s/%s", ui.getAbsolutePath().toString(), request.file.getFilePath()));

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/Aggregator.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/Aggregator.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/Aggregator.java
index e5fae95..687298e 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/Aggregator.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/Aggregator.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.hive.persistence.utils.Indexed;
 import org.apache.ambari.view.hive.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.hive.persistence.utils.OnlyOwnersFilteringStrategy;
 import org.apache.ambari.view.hive.resources.IResourceManager;
+import org.apache.ambari.view.hive.resources.files.FileService;
 import org.apache.ambari.view.hive.resources.jobs.atsJobs.HiveQueryId;
 import org.apache.ambari.view.hive.resources.jobs.atsJobs.IATSParser;
 import org.apache.ambari.view.hive.resources.jobs.atsJobs.TezDagId;
@@ -192,7 +193,7 @@ public class Aggregator {
     String query = atsHiveQuery.query;
     atsJob.setTitle(query.substring(0, (query.length() > 42)?42:query.length()));
 
-    atsJob.setQueryFile("fakefile://" + Base64.encodeBase64URLSafeString(query.getBytes()));  // fake queryFile
+    atsJob.setQueryFile(FileService.JSON_PATH_FILE + atsHiveQuery.url + "#otherinfo.QUERY!queryText");
     return atsJob;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ConnectionController.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ConnectionController.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ConnectionController.java
index c52d7b5..f481993 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ConnectionController.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ConnectionController.java
@@ -20,6 +20,7 @@ package org.apache.ambari.view.hive.resources.jobs;
 
 import org.apache.ambari.view.hive.client.Connection;
 import org.apache.ambari.view.hive.client.HiveClientException;
+import org.apache.ambari.view.hive.utils.HiveClientFormattedException;
 import org.apache.ambari.view.hive.utils.ServiceFormattedException;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.hive.service.cli.thrift.TOperationHandle;
@@ -35,12 +36,8 @@ public class ConnectionController {
     this.operationHandleControllerFactory = operationHandleControllerFactory;
   }
 
-  public TSessionHandle getSessionByTag(String tag) {
-    try {
-      return connection.getSessionByTag(tag);
-    } catch (HiveClientException e) {
-      throw new ServiceFormattedException(e.toString(), e);
-    }
+  public TSessionHandle getSessionByTag(String tag) throws HiveClientException {
+    return connection.getSessionByTag(tag);
   }
 
   public String openSession() {
@@ -48,7 +45,7 @@ public class ConnectionController {
       TSessionHandle sessionHandle = connection.openSession();
       return getTagBySession(sessionHandle);
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException(e.toString(), e);
+      throw new HiveClientFormattedException(e);
     }
   }
 
@@ -60,7 +57,7 @@ public class ConnectionController {
     try {
       connection.executeSync(session, "use " + database + ";");
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException(e.toString(), e);
+      throw new HiveClientFormattedException(e);
     }
   }
 
@@ -69,7 +66,7 @@ public class ConnectionController {
     try {
       operationHandle = connection.executeAsync(session, cmd);
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException(e.toString(), e);
+      throw new HiveClientFormattedException(e);
     }
     return operationHandleControllerFactory.createControllerForHandle(operationHandle);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java
index 1a6f7bf..3c1895b 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/JobService.java
@@ -22,7 +22,9 @@ import com.google.inject.Inject;
 import org.apache.ambari.view.ViewResourceHandler;
 import org.apache.ambari.view.hive.BaseService;
 import org.apache.ambari.view.hive.backgroundjobs.BackgroundJobController;
+import org.apache.ambari.view.hive.client.Connection;
 import org.apache.ambari.view.hive.client.Cursor;
+import org.apache.ambari.view.hive.client.HiveClientException;
 import org.apache.ambari.view.hive.persistence.utils.ItemNotFound;
 import org.apache.ambari.view.hive.resources.jobs.atsJobs.ATSRequestsDelegate;
 import org.apache.ambari.view.hive.resources.jobs.atsJobs.ATSRequestsDelegateImpl;
@@ -125,7 +127,7 @@ public class JobService extends BaseService {
     try {
       mergedJob = getAggregator().readATSJob(hiveJob);
     } catch (ItemNotFound itemNotFound) {
-      throw new ServiceFormattedException("Job not found", itemNotFound);
+      throw new ServiceFormattedException("E010 Job not found", itemNotFound);
     }
     Map createdJobMap = PropertyUtils.describe(mergedJob);
     createdJobMap.remove("class"); // no need to show Bean class on client
@@ -143,6 +145,7 @@ public class JobService extends BaseService {
   @Produces("text/csv")
   public Response getResultsCSV(@PathParam("jobId") String jobId,
                                 @Context HttpServletResponse response,
+                                @QueryParam("fileName") String fileName,
                                 @QueryParam("columns") final String requestedColumns) {
     try {
       JobController jobController = getResourceManager().readController(jobId);
@@ -155,6 +158,13 @@ public class JobService extends BaseService {
           Writer writer = new BufferedWriter(new OutputStreamWriter(os));
           CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT);
           try {
+
+            try {
+              csvPrinter.printRecord(resultSet.getHeadersRow().getRow());
+            } catch (HiveClientException e) {
+              LOG.error("Error on reading results header", e);
+            }
+
             while (resultSet.hasNext()) {
               csvPrinter.printRecord(resultSet.next().getRow());
               writer.flush();
@@ -165,7 +175,13 @@ public class JobService extends BaseService {
         }
       };
 
-      return Response.ok(stream).build();
+      if (fileName == null || fileName.isEmpty()) {
+        fileName = "results.csv";
+      }
+
+      return Response.ok(stream).
+          header("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName)).
+          build();
     } catch (WebApplicationException ex) {
       throw ex;
     } catch (ItemNotFound itemNotFound) {
@@ -216,11 +232,11 @@ public class JobService extends BaseService {
               stream.close();
 
             } catch (IOException e) {
-              throw new ServiceFormattedException("Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
+              throw new ServiceFormattedException("F010 Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
             } catch (InterruptedException e) {
-              throw new ServiceFormattedException("Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
+              throw new ServiceFormattedException("F010 Could not write CSV to HDFS for job#" + jobController.getJob().getId(), e);
             } catch (ItemNotFound itemNotFound) {
-              throw new NotFoundFormattedException("Job results are expired", itemNotFound);
+              throw new NotFoundFormattedException("E020 Job results are expired", itemNotFound);
             }
 
           }
@@ -261,6 +277,8 @@ public class JobService extends BaseService {
                              @QueryParam("columns") final String requestedColumns) {
     try {
       final JobController jobController = getResourceManager().readController(jobId);
+      if (!jobController.hasResults())
+        return ResultsPaginationController.emptyResponse().build();
 
       return ResultsPaginationController.getInstance(context)
            .request(jobId, searchId, true, fromBeginning, count,
@@ -385,6 +403,52 @@ public class JobService extends BaseService {
   }
 
   /**
+   * Invalidate session
+   */
+  @DELETE
+  @Path("sessions/{sessionTag}")
+  public Response invalidateSession(@PathParam("sessionTag") String sessionTag) {
+    try {
+      Connection connection = getSharedObjectsFactory().getHiveConnection();
+      connection.invalidateSessionByTag(sessionTag);
+      return Response.ok().build();
+    } catch (WebApplicationException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new ServiceFormattedException(ex.getMessage(), ex);
+    }
+  }
+
+  /**
+   * Session status
+   */
+  @GET
+  @Path("sessions/{sessionTag}")
+  @Produces(MediaType.APPLICATION_JSON)
+  public Response sessionStatus(@PathParam("sessionTag") String sessionTag) {
+    try {
+      Connection connection = getSharedObjectsFactory().getHiveConnection();
+
+      JSONObject session = new JSONObject();
+      session.put("sessionTag", sessionTag);
+      try {
+        connection.getSessionByTag(sessionTag);
+        session.put("actual", true);
+      } catch (HiveClientException ex) {
+        session.put("actual", false);
+      }
+
+      JSONObject status = new JSONObject();
+      status.put("session", session);
+      return Response.ok(status).build();
+    } catch (WebApplicationException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new ServiceFormattedException(ex.getMessage(), ex);
+    }
+  }
+
+  /**
    * Wrapper object for json mapping
    */
   public static class JobRequest {

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/NoOperationStatusSetException.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/NoOperationStatusSetException.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/NoOperationStatusSetException.java
index 1c1ce91..020c63e 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/NoOperationStatusSetException.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/NoOperationStatusSetException.java
@@ -19,8 +19,5 @@
 package org.apache.ambari.view.hive.resources.jobs;
 
 
-public class NoOperationStatusSetException extends Throwable {
-  public NoOperationStatusSetException(String s) {
-    super(s);
-  }
+public class NoOperationStatusSetException extends Exception {
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleController.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleController.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleController.java
index e146d55..34fc2d9 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleController.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleController.java
@@ -23,7 +23,7 @@ import org.apache.ambari.view.hive.client.Cursor;
 import org.apache.ambari.view.hive.client.HiveClientException;
 import org.apache.ambari.view.hive.client.IConnectionFactory;
 import org.apache.ambari.view.hive.resources.jobs.viewJobs.Job;
-import org.apache.ambari.view.hive.utils.ServiceFormattedException;
+import org.apache.ambari.view.hive.utils.HiveClientFormattedException;
 import org.apache.hive.service.cli.thrift.TGetOperationStatusResp;
 import org.apache.hive.service.cli.thrift.TOperationHandle;
 import org.slf4j.Logger;
@@ -51,49 +51,54 @@ public class OperationHandleController {
     this.operationHandle = storedOperationHandle;
   }
 
-  public String getOperationStatus() throws NoOperationStatusSetException, HiveClientException {
+  public OperationStatus getOperationStatus() throws NoOperationStatusSetException, HiveClientException {
     TGetOperationStatusResp statusResp = connectionsFabric.getHiveConnection().getOperationStatus(operationHandle);
+
     if (!statusResp.isSetOperationState()) {
-      throw new NoOperationStatusSetException("Operation state is not set");
+      throw new NoOperationStatusSetException();
     }
 
-    String status;
+    OperationStatus opStatus = new OperationStatus();
+    opStatus.sqlState = statusResp.getSqlState();
+    opStatus.message = statusResp.getErrorMessage();
+
     switch (statusResp.getOperationState()) {
       case INITIALIZED_STATE:
-        status = Job.JOB_STATE_INITIALIZED;
+        opStatus.status = Job.JOB_STATE_INITIALIZED;
         break;
       case RUNNING_STATE:
-        status = Job.JOB_STATE_RUNNING;
+        opStatus.status = Job.JOB_STATE_RUNNING;
         break;
       case FINISHED_STATE:
-        status = Job.JOB_STATE_FINISHED;
+        opStatus.status = Job.JOB_STATE_FINISHED;
         break;
       case CANCELED_STATE:
-        status = Job.JOB_STATE_CANCELED;
+        opStatus.status = Job.JOB_STATE_CANCELED;
         break;
       case CLOSED_STATE:
-        status = Job.JOB_STATE_CLOSED;
+        opStatus.status = Job.JOB_STATE_CLOSED;
         break;
       case ERROR_STATE:
-        status = Job.JOB_STATE_ERROR;
+        opStatus.status = Job.JOB_STATE_ERROR;
         break;
       case UKNOWN_STATE:
-        status = Job.JOB_STATE_UNKNOWN;
+        opStatus.status = Job.JOB_STATE_UNKNOWN;
         break;
       case PENDING_STATE:
-        status = Job.JOB_STATE_PENDING;
+        opStatus.status = Job.JOB_STATE_PENDING;
         break;
       default:
-        throw new NoOperationStatusSetException("Unknown status " + statusResp.getOperationState());
+        throw new NoOperationStatusSetException();
     }
-    return status;
+
+    return opStatus;
   }
 
   public void cancel() {
     try {
       connectionsFabric.getHiveConnection().cancelOperation(operationHandle);
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException("Cancel failed: " + e.toString(), e);
+      throw new HiveClientFormattedException(e);
     }
   }
 
@@ -108,4 +113,14 @@ public class OperationHandleController {
   public Cursor getResults() {
     return connectionsFabric.getHiveConnection().getResults(operationHandle);
   }
+
+  public boolean hasResults() {
+    return operationHandle.isHasResultSet();
+  }
+
+  public static class OperationStatus {
+    public String status;
+    public String sqlState;
+    public String message;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleResourceManager.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleResourceManager.java
index bab30a0..9e49dd1 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleResourceManager.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/OperationHandleResourceManager.java
@@ -65,7 +65,7 @@ public class OperationHandleResourceManager extends SharedCRUDResourceManager<St
       try {
         update(handle, jobRelatedHandles.get(0).getId());
       } catch (ItemNotFound itemNotFound) {
-        throw new ServiceFormattedException("Error when updating operation handle: " + itemNotFound.toString(), itemNotFound);
+        throw new ServiceFormattedException("E050 Error when updating operation handle: " + itemNotFound.toString(), itemNotFound);
       }
     } else {
       create(handle);

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ResultsPaginationController.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ResultsPaginationController.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ResultsPaginationController.java
index c152b03..8305708 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ResultsPaginationController.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/ResultsPaginationController.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.hive.client.ColumnDescription;
 import org.apache.ambari.view.hive.client.HiveClientException;
 import org.apache.ambari.view.hive.client.Cursor;
+import org.apache.ambari.view.hive.utils.HiveClientFormattedException;
 import org.apache.ambari.view.hive.utils.ServiceFormattedException;
 import org.apache.commons.collections4.map.PassiveExpiringMap;
 
@@ -96,6 +97,8 @@ public class ResultsPaginationController {
       Cursor resultSet = null;
       try {
         resultSet = makeResultsSet.call();
+      } catch (HiveClientException ex) {
+        throw new HiveClientFormattedException(ex);
       } catch (Exception ex) {
         throw new ServiceFormattedException(ex.getMessage(), ex);
       }
@@ -127,6 +130,18 @@ public class ResultsPaginationController {
     resultsResponse.setHasNext(resultSet.hasNext());
 //      resultsResponse.setSize(resultSet.size());
     resultsResponse.setOffset(resultSet.getOffset());
+    resultsResponse.setHasResults(true);
+    return Response.ok(resultsResponse);
+  }
+
+  public static Response.ResponseBuilder emptyResponse() {
+    ResultsResponse resultsResponse = new ResultsResponse();
+    resultsResponse.setSchema(new ArrayList<ColumnDescription>());
+    resultsResponse.setRows(new ArrayList<Object[]>());
+    resultsResponse.setReadCount(0);
+    resultsResponse.setHasNext(false);
+    resultsResponse.setOffset(0);
+    resultsResponse.setHasResults(false);
     return Response.ok(resultsResponse);
   }
 
@@ -136,6 +151,7 @@ public class ResultsPaginationController {
     private int readCount;
     private boolean hasNext;
     private long offset;
+    private boolean hasResults;
 
     public void setSchema(ArrayList<ColumnDescription> schema) {
       this.schema = schema;
@@ -176,5 +192,13 @@ public class ResultsPaginationController {
     public void setOffset(long offset) {
       this.offset = offset;
     }
+
+    public boolean getHasResults() {
+      return hasResults;
+    }
+
+    public void setHasResults(boolean hasResults) {
+      this.hasResults = hasResults;
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/StoredOperationHandle.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/StoredOperationHandle.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/StoredOperationHandle.java
index 1d3f6e0..a1d87ad 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/StoredOperationHandle.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/StoredOperationHandle.java
@@ -80,7 +80,7 @@ public class StoredOperationHandle implements Indexed {
       identifier.setGuid(Hex.decodeHex(getGuid().toCharArray()));
       identifier.setSecret(Hex.decodeHex(getSecret().toCharArray()));
     } catch (DecoderException e) {
-      throw new ServiceFormattedException("Wrong identifer of OperationHandle is stored in DB");
+      throw new ServiceFormattedException("E060 Wrong identifier of OperationHandle is stored in DB");
     }
     handle.setOperationId(identifier);
     return handle;

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java
index 106babd..a6446ff 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java
@@ -91,6 +91,7 @@ public class ATSParser implements IATSParser {
     HiveQueryId parsedJob = new HiveQueryId();
 
     parsedJob.entity = (String) job.get("entity");
+    parsedJob.url = delegate.hiveQueryIdDirectUrl((String) job.get("entity"));
     parsedJob.starttime = ((Long) job.get("starttime")) / MillisInSecond;
 
     JSONObject primaryfilters = (JSONObject) job.get("primaryfilters");

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegate.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegate.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegate.java
index 3aa07d4..f9b19bf 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegate.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegate.java
@@ -21,6 +21,14 @@ package org.apache.ambari.view.hive.resources.jobs.atsJobs;
 import org.json.simple.JSONObject;
 
 public interface ATSRequestsDelegate {
+  String hiveQueryIdDirectUrl(String entity);
+
+  String hiveQueryIdOperationIdUrl(String operationId);
+
+  String tezDagDirectUrl(String entity);
+
+  String tezDagNameUrl(String name);
+
   JSONObject hiveQueryIdList(String username);
 
   JSONObject hiveQueryIdByOperationId(String operationId);

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java
index 047bd63..6ac5ef8 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSRequestsDelegateImpl.java
@@ -43,6 +43,26 @@ public class ATSRequestsDelegateImpl implements ATSRequestsDelegate {
   }
 
   @Override
+  public String hiveQueryIdDirectUrl(String entity) {
+    return atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID/" + entity;
+  }
+
+  @Override
+  public String hiveQueryIdOperationIdUrl(String operationId) {
+    return atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID?primaryFilter=operationid:" + operationId;
+  }
+
+  @Override
+  public String tezDagDirectUrl(String entity) {
+    return atsUrl + "/ws/v1/timeline/TEZ_DAG_ID/" + entity;
+  }
+
+  @Override
+  public String tezDagNameUrl(String name) {
+    return atsUrl + "/ws/v1/timeline/TEZ_DAG_ID?primaryFilter=dagName:" + name;
+  }
+
+  @Override
   public JSONObject hiveQueryIdList(String username) {
     String hiveQueriesListUrl = atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID?primaryFilter=requestuser:" + username;
     String response = readFromWithDefault(hiveQueriesListUrl, "{ \"entities\" : [  ] }");
@@ -51,14 +71,14 @@ public class ATSRequestsDelegateImpl implements ATSRequestsDelegate {
 
   @Override
   public JSONObject hiveQueryIdByOperationId(String operationId) {
-    String hiveQueriesListUrl = atsUrl + "/ws/v1/timeline/HIVE_QUERY_ID?primaryFilter=operationid:" + operationId;
+    String hiveQueriesListUrl = hiveQueryIdOperationIdUrl(operationId);
     String response = readFromWithDefault(hiveQueriesListUrl, "{ \"entities\" : [  ] }");
     return (JSONObject) JSONValue.parse(response);
   }
 
   @Override
   public JSONObject tezDagByName(String name) {
-    String tezDagUrl = atsUrl + "/ws/v1/timeline/TEZ_DAG_ID?primaryFilter=dagName:" + name;
+    String tezDagUrl = tezDagNameUrl(name);
     String response = readFromWithDefault(tezDagUrl, EMPTY_ENTITIES_JSON);
     return (JSONObject) JSONValue.parse(response);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/HiveQueryId.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/HiveQueryId.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/HiveQueryId.java
index edb726b..af54dbb 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/HiveQueryId.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/HiveQueryId.java
@@ -23,6 +23,8 @@ import org.json.simple.JSONObject;
 import java.util.List;
 
 public class HiveQueryId {
+  public String url;
+
   public String entity;
   public String query;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java
index 65c36a7..dc4dfa8 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java
@@ -104,4 +104,12 @@ public interface Job extends Serializable,Indexed,PersonalResource {
   String getSessionTag();
 
   void setSessionTag(String sessionTag);
+
+  String getSqlState();
+
+  void setSqlState(String sqlState);
+
+  String getStatusMessage();
+
+  void setStatusMessage(String message);
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobController.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobController.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobController.java
index 339e194..a25f7d4 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobController.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobController.java
@@ -35,6 +35,7 @@ public interface JobController {
   Job getJobPOJO();
 
   Cursor getResults() throws ItemNotFound;
+  boolean hasResults() throws ItemNotFound;
 
   void afterCreation();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobControllerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobControllerImpl.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobControllerImpl.java
index c6c1c78..eb2e141 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobControllerImpl.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobControllerImpl.java
@@ -77,9 +77,9 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
     try {
       query = paginator.readPage(0);  //warning - reading only 0 page restricts size of query to 1MB
     } catch (IOException e) {
-      throw new ServiceFormattedException("Error when reading file: " + e.toString(), e);
+      throw new ServiceFormattedException("F030 Error when reading file " + job.getQueryFile(), e);
     } catch (InterruptedException e) {
-      throw new ServiceFormattedException("Error when reading file: " + e.toString(), e);
+      throw new ServiceFormattedException("F030 Error when reading file " + job.getQueryFile(), e);
     }
     return query;
   }
@@ -109,12 +109,19 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
   }
 
   private TSessionHandle getSession() {
-    if (job.getSessionTag() != null) {
-      return hiveConnection.getSessionByTag(getJob().getSessionTag());
-    } else {
-      String tag = hiveConnection.openSession();
-      job.setSessionTag(tag);
+    try {
+      if (job.getSessionTag() != null)
+        return hiveConnection.getSessionByTag(getJob().getSessionTag());
+    } catch (HiveClientException ignore) {
+      LOG.debug("Stale sessionTag was provided, new session will be opened");
+    }
+
+    String tag = hiveConnection.openSession();
+    job.setSessionTag(tag);
+    try {
       return hiveConnection.getSessionByTag(tag);
+    } catch (HiveClientException e) {
+      throw new HiveClientFormattedException(e);
     }
   }
 
@@ -136,8 +143,10 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
     try {
 
       OperationHandleController handle = opHandleControllerFactory.getHandleForJob(job);
-      String status = handle.getOperationStatus();
-      job.setStatus(status);
+      OperationHandleController.OperationStatus status = handle.getOperationStatus();
+      job.setStatus(status.status);
+      job.setStatusMessage(status.message);
+      job.setSqlState(status.sqlState);
       LOG.debug("Status of job#" + job.getId() + " is " + job.getStatus());
 
     } catch (NoOperationStatusSetException e) {
@@ -148,7 +157,7 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
       job.setStatus(Job.JOB_STATE_UNKNOWN);
 
     } catch (HiveClientException e) {
-      throw new ServiceFormattedException("Could not fetch job status " + job.getId(), e);
+      throw new HiveClientFormattedException(e);
 
     } catch (ItemNotFound itemNotFound) {
       LOG.debug("No TOperationHandle for job#" + job.getId() + ", can't update status");
@@ -213,6 +222,12 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
   }
 
   @Override
+  public boolean hasResults() throws ItemNotFound {
+    OperationHandleController handle = opHandleControllerFactory.getHandleForJob(job);
+    return handle.hasResults();
+  }
+
+  @Override
   public void afterCreation() {
     setupStatusDirIfNotPresent();
     setupQueryFileIfNotPresent();
@@ -311,9 +326,9 @@ public class JobControllerImpl implements JobController, ModifyNotificationDeleg
       }
 
     } catch (IOException e) {
-      throw new ServiceFormattedException("Error in creation: " + e.toString(), e);
+      throw new ServiceFormattedException("F040 Error when creating file " + jobQueryFilePath, e);
     } catch (InterruptedException e) {
-      throw new ServiceFormattedException("Error in creation: " + e.toString(), e);
+      throw new ServiceFormattedException("F040 Error when creating file " + jobQueryFilePath, e);
     }
     job.setQueryFile(jobQueryFilePath);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java
index d0d74a2..dc3f624 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java
@@ -20,6 +20,7 @@ package org.apache.ambari.view.hive.resources.jobs.viewJobs;
 
 import org.apache.commons.beanutils.PropertyUtils;
 
+import java.beans.Transient;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Map;
 
@@ -32,11 +33,14 @@ public class JobImpl implements Job {
   private String statusDir = null;
   private Long dateSubmitted = 0L;
   private Long duration = 0L;
-  private String status = JOB_STATE_UNKNOWN;
   private String forcedContent = null;
   private String dataBase = null;
   private String queryId = null;
 
+  private String status = JOB_STATE_UNKNOWN;
+  private String statusMessage = null;
+  private String sqlState = null;
+
   private String applicationId;
   private String dagId;
   private String dagName;
@@ -148,11 +152,13 @@ public class JobImpl implements Job {
   }
 
   @Override
+  @Transient
   public String getForcedContent() {
     return forcedContent;
   }
 
   @Override
+  @Transient
   public void setForcedContent(String forcedContent) {
     this.forcedContent = forcedContent;
   }
@@ -246,4 +252,24 @@ public class JobImpl implements Job {
   public void setSessionTag(String sessionTag) {
     this.sessionTag = sessionTag;
   }
+
+  @Override
+  public String getStatusMessage() {
+    return statusMessage;
+  }
+
+  @Override
+  public void setStatusMessage(String statusMessage) {
+    this.statusMessage = statusMessage;
+  }
+
+  @Override
+  public String getSqlState() {
+    return sqlState;
+  }
+
+  @Override
+  public void setSqlState(String sqlState) {
+    this.sqlState = sqlState;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/udfs/UDF.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/udfs/UDF.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/udfs/UDF.java
index 2dafcf4..77c37b5 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/udfs/UDF.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/udfs/UDF.java
@@ -31,7 +31,7 @@ import java.util.Map;
 public class UDF implements Serializable, PersonalResource {
   private String name;
   private String classname;
-  private Integer fileResource;
+  private String fileResource;
 
   private String id;
   private String owner;
@@ -77,11 +77,11 @@ public class UDF implements Serializable, PersonalResource {
     this.classname = classname;
   }
 
-  public Integer getFileResource() {
+  public String getFileResource() {
     return fileResource;
   }
 
-  public void setFileResource(Integer fileResource) {
+  public void setFileResource(String fileResource) {
     this.fileResource = fileResource;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsApi.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsApi.java
index e5e3593..844bc80 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsApi.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsApi.java
@@ -253,7 +253,7 @@ public class HdfsApi {
       }
     });
     if (!result) {
-      throw new ServiceFormattedException("Can't copy source file from " + src + " to " + dest);
+      throw new ServiceFormattedException("F050 Can't copy source file from " + src + " to " + dest);
     }
   }
 
@@ -341,11 +341,11 @@ public class HdfsApi {
       api = new HdfsApi(defaultFS, getHdfsUsername(context), getHdfsAuthParams(context));
       LOG.info("HdfsApi connected OK");
     } catch (IOException e) {
-      String message = "HdfsApi IO error: " + e.getMessage();
+      String message = "F060 Couldn't open connection to HDFS";
       LOG.error(message);
       throw new ServiceFormattedException(message, e);
     } catch (InterruptedException e) {
-      String message = "HdfsApi Interrupted error: " + e.getMessage();
+      String message = "F060 Couldn't open connection to HDFS";
       LOG.error(message);
       throw new ServiceFormattedException(message, e);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsUtil.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsUtil.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsUtil.java
index 3120958..7386ee4 100644
--- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsUtil.java
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HdfsUtil.java
@@ -43,9 +43,9 @@ public class HdfsUtil {
         stream.close();
       }
     } catch (IOException e) {
-      throw new ServiceFormattedException("Could not write file " + filePath, e);
+      throw new ServiceFormattedException("F070 Could not write file " + filePath, e);
     } catch (InterruptedException e) {
-      throw new ServiceFormattedException("Could not write file " + filePath, e);
+      throw new ServiceFormattedException("F070 Could not write file " + filePath, e);
     }
   }
 
@@ -74,9 +74,9 @@ public class HdfsUtil {
         triesCount += 1;
       } while (!isUnallocatedFilenameFound);
     } catch (IOException e) {
-      throw new ServiceFormattedException("Error in creation: " + e.toString(), e);
+      throw new ServiceFormattedException("F080 Error in creation " + fullPathAndFilename + "...", e);
     } catch (InterruptedException e) {
-      throw new ServiceFormattedException("Error in creation: " + e.toString(), e);
+      throw new ServiceFormattedException("F080 Error in creation " + fullPathAndFilename + "...", e);
     }
 
     return newFilePath;

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HiveClientFormattedException.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HiveClientFormattedException.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HiveClientFormattedException.java
new file mode 100644
index 0000000..a602d22
--- /dev/null
+++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/utils/HiveClientFormattedException.java
@@ -0,0 +1,26 @@
+/**
+ * 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.ambari.view.hive.utils;
+
+public class HiveClientFormattedException extends ServiceFormattedException {
+
+  public HiveClientFormattedException(Throwable exception) {
+    super(exception.getMessage(), exception);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/.bowerrc
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/.bowerrc b/contrib/views/hive/src/main/resources/ui/hive-web/.bowerrc
new file mode 100644
index 0000000..959e169
--- /dev/null
+++ b/contrib/views/hive/src/main/resources/ui/hive-web/.bowerrc
@@ -0,0 +1,4 @@
+{
+  "directory": "bower_components",
+  "analytics": false
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/.editorconfig
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/.editorconfig b/contrib/views/hive/src/main/resources/ui/hive-web/.editorconfig
new file mode 100644
index 0000000..47c5438
--- /dev/null
+++ b/contrib/views/hive/src/main/resources/ui/hive-web/.editorconfig
@@ -0,0 +1,34 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+
+[*.js]
+indent_style = space
+indent_size = 2
+
+[*.hbs]
+insert_final_newline = false
+indent_style = space
+indent_size = 2
+
+[*.css]
+indent_style = space
+indent_size = 2
+
+[*.html]
+indent_style = space
+indent_size = 2
+
+[*.{diff,md}]
+trim_trailing_whitespace = false

http://git-wip-us.apache.org/repos/asf/ambari/blob/672eee34/contrib/views/hive/src/main/resources/ui/hive-web/.ember-cli
----------------------------------------------------------------------
diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/.ember-cli b/contrib/views/hive/src/main/resources/ui/hive-web/.ember-cli
new file mode 100644
index 0000000..3da2738
--- /dev/null
+++ b/contrib/views/hive/src/main/resources/ui/hive-web/.ember-cli
@@ -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.
+ */
+
+{
+  /**
+    Ember CLI sends analytics information by default. The data is completely
+    anonymous, but there are times when you might want to disable this behavior.
+
+    Setting `disableAnalytics` to true will prevent any data from being sent.
+  */
+  "disableAnalytics": true
+}