ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dbhowm...@apache.org
Subject ambari git commit: AMBARI-18670. Hive view 1.0/1.5 does not refresh LDAP credentials for user. (Ashwin Rajeev via dipayanb)
Date Wed, 02 Nov 2016 19:00:02 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.4 a5a40dfc2 -> e8958d701


AMBARI-18670. Hive view 1.0/1.5 does not refresh LDAP credentials for user. (Ashwin Rajeev
via dipayanb)


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

Branch: refs/heads/branch-2.4
Commit: e8958d7011cb2993f616e284a8c5ee8c1caa1284
Parents: a5a40df
Author: Dipayan Bhowmick <dipayan.bhowmick@gmail.com>
Authored: Thu Nov 3 00:23:03 2016 +0530
Committer: Dipayan Bhowmick <dipayan.bhowmick@gmail.com>
Committed: Thu Nov 3 00:28:48 2016 +0530

----------------------------------------------------------------------
 .../ambari/view/hive2/ConnectionFactory.java    |  19 ++-
 .../ambari/view/hive2/ConnectionSystem.java     |  18 ++-
 .../ambari/view/hive2/actor/JdbcConnector.java  |   4 +-
 .../view/hive2/client/AsyncJobRunner.java       |   1 -
 .../view/hive2/client/AsyncJobRunnerImpl.java   |   2 -
 .../view/hive2/client/ConnectionConfig.java     |   7 +-
 .../ambari/view/hive2/internal/Connectable.java |   6 +
 .../hive2/internal/HiveConnectionWrapper.java   |  18 +++
 .../resources/browser/ConnectionService.java    | 155 +++++++++++++++++++
 .../resources/browser/HiveBrowserService.java   |   4 +-
 .../view/hive2/resources/jobs/JobService.java   |  31 ++--
 .../app/controllers/index/history-query/logs.js |  22 ++-
 .../ui/hive-web/app/controllers/splash.js       |  35 ++++-
 .../ui/hive-web/app/initializers/i18n.js        |   1 +
 .../resources/ui/hive-web/app/routes/splash.js  |  52 ++++++-
 .../resources/ui/hive-web/app/services/ldap.js  |  59 +++++++
 .../ui/hive-web/app/utils/constants.js          |   1 +
 .../views/hive-next/src/main/resources/view.xml |  15 ++
 18 files changed, 409 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionFactory.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionFactory.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionFactory.java
index 7295f3a..483f5b8 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionFactory.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionFactory.java
@@ -20,6 +20,7 @@ package org.apache.ambari.view.hive2;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
 import com.google.common.base.Strings;
 import com.google.common.collect.FluentIterable;
 import org.apache.ambari.view.ViewContext;
@@ -41,15 +42,24 @@ public class ConnectionFactory {
 
   private static final String HIVE_JDBC_URL_KEY = "hive.jdbc.url";
   private static final String HIVE_SESSION_PARAMS = "hive.session.params";
+  private static final String HIVE_LDAP_CONFIG = "hive.ldap.configured";
 
   private static final String BINARY_PORT_KEY = "hive.server2.thrift.port";
+  private static final String HIVE_AUTH_MODE = "hive.server2.authentication";
   private static final String HTTP_PORT_KEY = "hive.server2.thrift.http.port";
   private static final String HIVE_TRANSPORT_MODE_KEY = "hive.server2.transport.mode";
   private static final String HTTP_PATH_KEY = "hive.server2.thrift.http.path";
   private static final String HS2_PROXY_USER = "hive.server2.proxy.user";
 
+  public static boolean isLdapEnabled(ViewContext context){
+    if (context.getCluster() == null) {
+      return context.getProperties().get(HIVE_LDAP_CONFIG).equalsIgnoreCase("true");
+    }
+    return context.getCluster().getConfigurationValue(HIVE_SITE,HIVE_AUTH_MODE).equalsIgnoreCase("ldap");
+  }
+
+  public static ConnectionConfig create(ViewContext context)  {
 
-  public static ConnectionConfig create(ViewContext context) {
     String jdbcUrl;
     if (context.getCluster() == null) {
       jdbcUrl = getConnectFromCustom(context);
@@ -62,9 +72,16 @@ public class ConnectionFactory {
     }
 
     String userName = context.getUsername();
+    if(isLdapEnabled(context)){
+      Optional<String> opPassword = ConnectionSystem.getInstance().getPassword(context);
+      if(opPassword.isPresent()){
+        return new ConnectionConfig(userName, opPassword.get(), jdbcUrl);
+      }
+    }
     return new ConnectionConfig(userName, "", jdbcUrl);
   }
 
+
   private static String getFromHiveConfiguration(ViewContext context) {
     String transportMode = context.getCluster().getConfigurationValue(HIVE_SITE, HIVE_TRANSPORT_MODE_KEY);
     String binaryPort = context.getCluster().getConfigurationValue(HIVE_SITE, BINARY_PORT_KEY);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionSystem.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionSystem.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionSystem.java
index f534130..e6e533f 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionSystem.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/ConnectionSystem.java
@@ -23,7 +23,7 @@ import akka.actor.ActorSystem;
 import akka.actor.Inbox;
 import akka.actor.PoisonPill;
 import akka.actor.Props;
-import com.google.common.collect.Multimap;
+import com.google.common.base.Optional;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.hive2.actor.DeathWatch;
 import org.apache.ambari.view.hive2.actor.OperationController;
@@ -31,6 +31,7 @@ import org.apache.ambari.view.hive2.internal.ConnectionSupplier;
 import org.apache.ambari.view.hive2.internal.DataStorageSupplier;
 import org.apache.ambari.view.hive2.internal.HdfsApiSupplier;
 import org.apache.ambari.view.hive2.internal.SafeViewContext;
+import org.apache.parquet.Strings;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -44,6 +45,9 @@ public class ConnectionSystem {
   private static final Object lock = new Object();
   private static Map<String, Map<String, ActorRef>> operationControllerMap =
new ConcurrentHashMap<>();
 
+  // credentials map stores usernames and passwords
+  private static Map<String, String> credentialsMap = new ConcurrentHashMap<>();
+
   private ConnectionSystem() {
     this.actorSystem = ActorSystem.create(ACTOR_SYSTEM_NAME);
     ;
@@ -98,6 +102,18 @@ public class ConnectionSystem {
     return ref;
   }
 
+  public synchronized void persistCredentials(String user,String password){
+    if(!Strings.isNullOrEmpty(password)){
+      credentialsMap.put(user,password);
+    }
+  }
+
+
+  public synchronized Optional<String> getPassword(ViewContext viewContext){
+    String pass = credentialsMap.get(viewContext.getUsername());
+    return Optional.fromNullable(pass);
+  }
+
   public void removeOperationControllerFromCache(String viewInstanceName) {
     Map<String, ActorRef> refs = operationControllerMap.remove(viewInstanceName);
     for (ActorRef ref : refs.values()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/actor/JdbcConnector.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/actor/JdbcConnector.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/actor/JdbcConnector.java
index 2a2f8f7..bb438d2 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/actor/JdbcConnector.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/actor/JdbcConnector.java
@@ -349,7 +349,9 @@ public class JdbcConnector extends HiveActor {
 
     Optional<HiveConnection> connectionOptional = connectable.getConnection();
     if (!connectionOptional.isPresent()) {
-      notifyConnectFailure(new SQLException("Hive connection is not created"));
+      SQLException sqlException = connectable.isUnauthorized() ? new SQLException("Hive Connection
not Authorized", "AUTHFAIL")
+              : new SQLException("Hive connection is not created");
+      notifyConnectFailure(sqlException);
       return false;
     }
     return true;

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunner.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunner.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunner.java
index 548dfae..421df8e 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunner.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunner.java
@@ -20,7 +20,6 @@ package org.apache.ambari.view.hive2.client;
 
 import com.google.common.base.Optional;
 import org.apache.ambari.view.hive2.actor.message.SQLStatementJob;
-import org.apache.ambari.view.hive2.actor.message.job.AsyncExecutionFailed;
 import org.apache.ambari.view.hive2.actor.message.job.Failure;
 import org.apache.ambari.view.hive2.resources.jobs.viewJobs.Job;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunnerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunnerImpl.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunnerImpl.java
index 286298a..182dfbc 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunnerImpl.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/AsyncJobRunnerImpl.java
@@ -31,13 +31,11 @@ import org.apache.ambari.view.hive2.actor.message.FetchResult;
 import org.apache.ambari.view.hive2.actor.message.ResetCursor;
 import org.apache.ambari.view.hive2.actor.message.ResultNotReady;
 import org.apache.ambari.view.hive2.actor.message.SQLStatementJob;
-import org.apache.ambari.view.hive2.actor.message.job.AsyncExecutionFailed;
 import org.apache.ambari.view.hive2.actor.message.job.CancelJob;
 import org.apache.ambari.view.hive2.actor.message.job.Failure;
 import org.apache.ambari.view.hive2.resources.jobs.viewJobs.Job;
 import org.apache.ambari.view.hive2.utils.ResultFetchFormattedException;
 import org.apache.ambari.view.hive2.utils.ResultNotReadyFormattedException;
-import org.apache.ambari.view.hive2.utils.ServiceFormattedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import scala.concurrent.duration.Duration;

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/ConnectionConfig.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/ConnectionConfig.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/ConnectionConfig.java
index 40cdd28..20f18ff 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/ConnectionConfig.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/client/ConnectionConfig.java
@@ -19,11 +19,10 @@
 package org.apache.ambari.view.hive2.client;
 
 import org.apache.ambari.view.hive2.actor.message.Connect;
-import org.apache.ambari.view.hive2.actor.message.HiveJob;
 
 public class ConnectionConfig {
   private final String username;
-  private final String password;
+  private String password;
   private final String jdbcUrl;
 
   public ConnectionConfig(String username, String password, String jdbcUrl) {
@@ -32,6 +31,10 @@ public class ConnectionConfig {
     this.jdbcUrl = jdbcUrl;
   }
 
+  public void setPassword(String password) {
+    this.password = password;
+  }
+
   public String getUsername() {
     return username;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/Connectable.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/Connectable.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/Connectable.java
index 5bfb6dc..926decc 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/Connectable.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/Connectable.java
@@ -56,4 +56,10 @@ public interface Connectable  {
      */
     void disconnect() throws ConnectionException;
 
+    /**
+     * True when the connection is unauthorized
+     * @return
+     */
+    boolean isUnauthorized();
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/HiveConnectionWrapper.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/HiveConnectionWrapper.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/HiveConnectionWrapper.java
index 811df23..3701016 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/HiveConnectionWrapper.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/internal/HiveConnectionWrapper.java
@@ -34,11 +34,13 @@ import java.sql.SQLException;
 public class HiveConnectionWrapper implements Connectable,Supplier<HiveConnection>
{
 
   private static String DRIVER_NAME = "org.apache.hive.jdbc.HiveDriver";
+  public static final String SUFFIX = "validating the login";
   private final String jdbcUrl;
   private final String username;
   private final String password;
 
   private HiveConnection connection = null;
+  private boolean authFailed;
 
   public HiveConnectionWrapper(String jdbcUrl, String username, String password) {
     this.jdbcUrl = jdbcUrl;
@@ -60,6 +62,8 @@ public class HiveConnectionWrapper implements Connectable,Supplier<HiveConnectio
       connection = (HiveConnection)conn;
 
     } catch (SQLException e) {
+      if(isLoginError(e))
+        this.authFailed = true;
       throw new ConnectionException(e, "Cannot open a hive connection with connect string
" + jdbcUrl);
     }
 
@@ -82,6 +86,20 @@ public class HiveConnectionWrapper implements Connectable,Supplier<HiveConnectio
     }
   }
 
+  private boolean isLoginError(SQLException ce) {
+    return ce.getCause().getMessage().toLowerCase().endsWith(SUFFIX);
+  }
+
+  /**
+   * True when the connection is unauthorized
+   *
+   * @return
+   */
+  @Override
+  public boolean isUnauthorized() {
+    return authFailed;
+  }
+
   public Optional<HiveConnection> getConnection() {
     return Optional.fromNullable(connection);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/ConnectionService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/ConnectionService.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/ConnectionService.java
new file mode 100644
index 0000000..eb1609d
--- /dev/null
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/ConnectionService.java
@@ -0,0 +1,155 @@
+/**
+ * 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.ambari.view.hive2.resources.browser;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.hive2.ConnectionFactory;
+import org.apache.ambari.view.hive2.ConnectionSystem;
+import org.apache.ambari.view.hive2.client.ConnectionConfig;
+import org.apache.ambari.view.hive2.internal.ConnectionException;
+import org.apache.ambari.view.hive2.internal.HiveConnectionWrapper;
+import org.apache.ambari.view.hive2.utils.ServiceFormattedException;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * Connection verification and management controller
+ */
+public class ConnectionService {
+
+    public static final String NO_PASSWORD = "";
+    public static final String SUFFIX = "validating the login";
+    @Inject
+  protected ViewContext context;
+
+  protected final static Logger LOG =
+    LoggerFactory.getLogger(ConnectionService.class);
+
+  /**
+   * Check if LDAP is configured on Hive
+   * if no password is cached , ask for one(401)
+   * if yes and a password is cached, try
+   * to connect, if connection succeeds
+   * return OK,
+   *
+   * if connection fails - ask for one again(401)
+   */
+  @GET
+  @Path("connect")
+  @Produces(MediaType.APPLICATION_JSON)
+
+  public Response attemptConnection() {
+    boolean ldapEnabled = ConnectionFactory.isLdapEnabled(context);
+    if(ldapEnabled) {
+      ConnectionSystem instance = ConnectionSystem.getInstance();
+      Optional<String> password = instance.getPassword(context);
+      if (!password.isPresent()) {
+        // No password cached - request for one
+        return Response.status(Response.Status.UNAUTHORIZED).build();
+      }
+      // if there was a password cached, make a connection attempt
+      // get the password
+        String pass = password.get();
+      // password may be stale, try to connect to Hive
+        return attemptHiveConnection(pass);
+    }
+      return attemptHiveConnection(NO_PASSWORD);
+
+  }
+
+
+    private Response getOKResponse() {
+        JSONObject response = new JSONObject();
+        response.put("message", "OK");
+        response.put("trace", null);
+        response.put("status", "200");
+        return Response.ok().entity(response).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    private Response attemptHiveConnection(String pass) {
+        ConnectionConfig connectionConfig = ConnectionFactory.create(context);
+        HiveConnectionWrapper hiveConnectionWrapper = new HiveConnectionWrapper(connectionConfig.getJdbcUrl(),
connectionConfig.getUsername(), pass);
+        try {
+          hiveConnectionWrapper.connect();
+        } catch (ConnectionException e) {
+          // Cannot connect with the current credentials
+          // check the message to see if the cause was a login failure
+          // return a 401
+          // else return a 500
+          if(isLoginError(e))
+            return Response.status(Response.Status.UNAUTHORIZED).build();
+          else
+              throw new ServiceFormattedException(e.getMessage(), e);
+        } finally {
+          try {
+            hiveConnectionWrapper.disconnect();
+          }
+        catch(ConnectionException e){
+           LOG.warn("Cannot close the connection");
+        }
+      }
+        return getOKResponse()  ;
+    }
+
+    private boolean isLoginError(ConnectionException ce) {
+        return ce.getCause().getMessage().toLowerCase().endsWith(SUFFIX);
+    }
+
+
+    /**
+     * Set password
+     * This just updates the caches.
+     */
+    @POST
+    @Path("auth")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response setupPassword(AuthRequest request) {
+        try {
+            //Cache the password for the user
+            ConnectionSystem instance = ConnectionSystem.getInstance();
+            instance.persistCredentials(context.getUsername(),request.password);
+            return getOKResponse();
+        } catch (WebApplicationException ex) {
+            throw ex;
+        } catch (Exception ex) {
+            throw new ServiceFormattedException(ex.getMessage(), ex);
+        }
+    }
+
+
+
+    public static class AuthRequest {
+        public String password;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/HiveBrowserService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/HiveBrowserService.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/HiveBrowserService.java
index 7481f9e..ba9fe29 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/HiveBrowserService.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/browser/HiveBrowserService.java
@@ -74,9 +74,11 @@ public class HiveBrowserService {
     else
       like = "*" + like + "*";
     JSONObject response = new JSONObject();
+    ConnectionConfig hiveConnectionConfig = getHiveConnectionConfig();
     DDLDelegator delegator = new DDLDelegatorImpl(context, ConnectionSystem.getInstance().getActorSystem(),
ConnectionSystem.getInstance().getOperationController(context));
-    List<String> databases = delegator.getDbList(getHiveConnectionConfig(), like);
+    List<String> databases = delegator.getDbList(hiveConnectionConfig, like);
     response.put("databases", databases);
+
     return Response.ok(response).build();
 
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/jobs/JobService.java
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/jobs/JobService.java
b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/jobs/JobService.java
index f054a9d..ff315e4 100644
--- a/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/jobs/JobService.java
+++ b/contrib/views/hive-next/src/main/java/org/apache/ambari/view/hive2/resources/jobs/JobService.java
@@ -23,6 +23,7 @@ import com.beust.jcommander.internal.Lists;
 import com.google.common.base.Optional;
 import org.apache.ambari.view.ViewResourceHandler;
 import org.apache.ambari.view.hive2.BaseService;
+import org.apache.ambari.view.hive2.ConnectionFactory;
 import org.apache.ambari.view.hive2.ConnectionSystem;
 import org.apache.ambari.view.hive2.actor.message.job.Failure;
 import org.apache.ambari.view.hive2.backgroundjobs.BackgroundJobController;
@@ -75,6 +76,7 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -137,8 +139,15 @@ public class JobService extends BaseService {
         ConnectionSystem system = ConnectionSystem.getInstance();
         final AsyncJobRunner asyncJobRunner = new AsyncJobRunnerImpl(context, system.getOperationController(context),
system.getActorSystem());
         Optional<Failure> error = asyncJobRunner.getError(jobId, context.getUsername());
+
         if(error.isPresent()){
-          throw new Exception(error.get().getError());
+          Throwable th = error.get().getError();
+          if(th instanceof SQLException){
+            SQLException sqlException = (SQLException) th;
+            if(sqlException.getSQLState().equals("AUTHFAIL") && ConnectionFactory.isLdapEnabled(context))
+              return Response.status(401).build();
+          }
+          throw new Exception(th);
         }
       }
 
@@ -543,27 +552,7 @@ public class JobService extends BaseService {
     }
   }
 
-  /**
-   * Set password and connect to Hive
-   */
-  @POST
-  @Path("auth")
-  @Consumes(MediaType.APPLICATION_JSON)
-  public Response setupPassword(AuthRequest request) {
-    try {
-      /*HiveAuthCredentials authCredentials = new HiveAuthCredentials();
-      authCredentials.setPassword(request.password);
-      new UserLocalHiveAuthCredentials().set(authCredentials, context);*/
 
-      //connectionLocal.remove(context);  // force reconnect on next get
-      //connectionLocal.get(context);
-      return Response.ok().status(200).build();
-    } catch (WebApplicationException ex) {
-      throw ex;
-    } catch (Exception ex) {
-      throw new ServiceFormattedException(ex.getMessage(), ex);
-    }
-  }
 
   /**
    * Remove connection credentials

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js
b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js
index 43c7a7e..2b5fd26 100644
--- a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js
@@ -23,6 +23,7 @@ import utils from 'hive/utils/functions';
 export default Ember.ObjectController.extend({
   fileService: Ember.inject.service(constants.namingConventions.file),
   notifyService: Ember.inject.service(constants.namingConventions.notify),
+  ldapService: Ember.inject.service(constants.namingConventions.ldap),
 
   needs: [ constants.namingConventions.queryTabs,
            constants.namingConventions.index,
@@ -32,12 +33,27 @@ export default Ember.ObjectController.extend({
   index: Ember.computed.alias('controllers.' + constants.namingConventions.index),
   openQueries: Ember.computed.alias('controllers.' + constants.namingConventions.openQueries),
 
+  requestLdapPassword:function(callback) {
+    var ldap = this.get('ldapService');
+    ldap.requestLdapPassword(this,callback);
+  },
+
   reloadJobLogs: function (job) {
     var self = this;
     var handleError = function (error) {
       job.set('isRunning', false);
-
-      self.get('notifyService').error(error);
+      // Check if error is 401
+      // show LDAP login and fail job
+      // show message to rerun job
+      if(error.status === 401){
+        self.requestLdapPassword(function(){
+          var err = {
+            message: Ember.I18n.t('alerts.success.query.rerun')
+          };
+          self.get('notifyService').error(err);
+        });
+      } else
+        self.get('notifyService').error(error);
     };
 
     job.reload().then(function () {
@@ -82,6 +98,8 @@ export default Ember.ObjectController.extend({
     });
   },
 
+
+
   isJobRunning: function (job) {
     return utils.insensitiveCompare(job.get('status'),
                                     constants.statuses.unknown,

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/splash.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/splash.js
b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/splash.js
index 6f495ed..97b3ea6 100644
--- a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/splash.js
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/controllers/splash.js
@@ -22,9 +22,36 @@ import constants from 'hive/utils/constants';
 export default Ember.Controller.extend({
 
   databaseService: Ember.inject.service(constants.namingConventions.database),
+  ldapService: Ember.inject.service(constants.namingConventions.ldap),
   isExpanded: false,
   errors: "",
   stackTrace: "",
+  requestLdapPassword:function(callback) {
+    var ldap = this.get('ldapService');
+    ldap.requestLdapPassword(this,callback);
+  },
+
+checkConnection: function() {
+    var model = this.get('model');
+    var url = this.container.lookup('adapter:application').buildURL() + '/resources/connection/';
+    var finalurl =  url + 'connect' ;
+    var self = this;
+
+    return Ember.$.getJSON( finalurl )
+        .then(
+            function(data) {
+              console.log("fulfil");
+              model.set('ldapSuccess',true);
+            },
+            function(reason) {
+              console.log("fail");
+              if(reason.status === 401){
+                model.set('ldapSuccess',false);
+              }
+            }
+        );
+
+  },
   startTests: function() {
 
     var model = this.get('model');
@@ -64,9 +91,11 @@ export default Ember.Controller.extend({
       model.set('percent', percent + 25);
     };
 
-    var promises = ['hdfs', 'hiveserver', 'ats', 'userhome'].map(function(name) {
 
-      var finalurl = ((name == 'hiveserver') ? self.get('databaseService.baseUrl') : (url
+ name + 'Status')) || '' ;
+
+    var promises = ['hdfs', 'ats', 'userhome'].map(function(name) {
+
+      var finalurl =  url + name + 'Status' ;
 
       return Ember.$.getJSON( finalurl )
         .then(
@@ -74,7 +103,7 @@ export default Ember.Controller.extend({
             processResponse(name, data);
           },
           function(reason) {
-            processResponse(name, reason.responseJSON);
+              processResponse(name, reason.responseJSON);
           }
         );
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/initializers/i18n.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/initializers/i18n.js
b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/initializers/i18n.js
index f7f7706..3d18c08 100644
--- a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/initializers/i18n.js
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/initializers/i18n.js
@@ -71,6 +71,7 @@ TRANSLATIONS = {
       },
       query: {
         execution: 'Query has been submitted.',
+        rerun: "Password updated, please execute the query again",
         save: 'The query has been saved.',
         update: 'The query has been updated.'
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/routes/splash.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/routes/splash.js b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/routes/splash.js
index b851bf1..6328256 100644
--- a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/routes/splash.js
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/routes/splash.js
@@ -42,14 +42,54 @@ export default Ember.Route.extend({
 
     controller.set('model', model);
     var self = this;
-    controller.startTests().then(function() {
 
-      if (model.get("hiveserverTest") && model.get("hdfsTest") && model.get("atsTest")
&& model.get("userhomeTest")) {
-        Ember.run.later(this, function() {
-          self.send('transition');
-        }, 2000);
-      }
+    function loadView(){
+          controller.startTests().then(function() {
+
+            if (model.get("hiveserverTest")
+                && model.get("hdfsTest")
+                && model.get("atsTest")
+                && model.get("userhomeTest")) {
+              Ember.run.later(this, function() {
+                self.send('transition');
+              }, 2000);
+            }
+          });
+        }
+
+    controller.checkConnection().then(function(){
+      var percent = model.get('percent');
+      model.set("hiveserverTest",true);
+      model.set("hiveserver" + 'TestDone', true);
+      model.set('percent', percent + 25);
+      loadView();
+    },function(){
+        if(!model.get('ldapSuccess')) {
+          var percent = model.get('percent');
+          controller.requestLdapPassword(function(){
+            // check the connection again
+            controller.checkConnection().then(function(){
+              model.set("hiveserverTest",true);
+              model.set("hiveserver" + 'TestDone', true);
+              model.set('percent', percent + 25);
+              loadView();
+            },function(){
+              var percent = model.get('percent');
+              var checkFailedMessage = "Hive authentication failed";
+              var errors = controller.get("errors");
+              errors += checkFailedMessage;
+              errors += '<br>';
+              controller.set("errors", errors);
+              model.get("hiveserverTest",false);
+              model.set("hiveserver" + 'TestDone', true);
+              model.set('percent', percent + 25);
+              loadView();
+            });
+          });
+        }
     });
+
+
   },
 
   actions: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/services/ldap.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/services/ldap.js b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/services/ldap.js
new file mode 100644
index 0000000..4a3098b
--- /dev/null
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/services/ldap.js
@@ -0,0 +1,59 @@
+/**
+ * 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 Ember from 'ember';
+
+export default Ember.Service.extend({
+
+  requestLdapPassword: function (context, callback) {
+
+    var url = context.container.lookup('adapter:application').buildURL() + '/resources/connection/';
+    var defer = Ember.RSVP.defer();
+    var self = context;
+
+    self.send('openModal', 'modal-save', {
+      heading: "modals.authenticationLDAP.heading",
+      text: "",
+      type: "password",
+      defer: defer
+    });
+
+    return defer.promise.then(function (text) {
+      // make a post call with the given ldap password.
+      var password = text;
+      var ldapAuthURL = url + "auth";
+
+      $.ajax({
+        url: ldapAuthURL,
+        type: 'post',
+        headers: {'X-Requested-With': 'XMLHttpRequest', 'X-Requested-By': 'ambari'},
+        contentType: 'application/json',
+        data: JSON.stringify({"password": password}),
+        success: function (data, textStatus, jQxhr) {
+          console.log("LDAP done: " + data);
+          callback();
+        },
+        error: function (jqXhr, textStatus, errorThrown) {
+          console.log("LDAP fail: " + errorThrown);
+          self.get('notifyService').error("Wrong Credentials.");
+        }
+      });
+    });
+
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/ui/hive-web/app/utils/constants.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/utils/constants.js
b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/utils/constants.js
index eb1548e..348454b 100644
--- a/contrib/views/hive-next/src/main/resources/ui/hive-web/app/utils/constants.js
+++ b/contrib/views/hive-next/src/main/resources/ui/hive-web/app/utils/constants.js
@@ -63,6 +63,7 @@ export default Ember.Object.create({
     jobs: 'jobs',
     savedQuery: 'saved-query',
     database: 'database',
+    ldap:'ldap',
     databases: 'databases',
     openQueries: 'open-queries',
     visualExplain: 'visual-explain',

http://git-wip-us.apache.org/repos/asf/ambari/blob/e8958d70/contrib/views/hive-next/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/hive-next/src/main/resources/view.xml b/contrib/views/hive-next/src/main/resources/view.xml
index 1754686..a2f9ce8 100644
--- a/contrib/views/hive-next/src/main/resources/view.xml
+++ b/contrib/views/hive-next/src/main/resources/view.xml
@@ -48,6 +48,15 @@
     </parameter>
 
     <parameter>
+        <name>hive.ldap.configured</name>
+        <description>Set to true if Hive server is configured through LDAP</description>
+        <label>Hive LDAP configuration</label>
+        <placeholder>false</placeholder>
+        <default-value>false</default-value>
+        <required>false</required>
+    </parameter>
+
+    <parameter>
         <name>hive.metastore.warehouse.dir</name>
         <description>Hive Metastore directory (example: /apps/hive/warehouse)</description>
         <label>Hive Metastore directory</label>
@@ -282,6 +291,12 @@
         <service-class>org.apache.ambari.view.hive2.HelpService</service-class>
     </resource>
 
+
+    <resource>
+        <name>connection</name>
+        <service-class>org.apache.ambari.view.hive2.resources.browser.ConnectionService</service-class>
+    </resource>
+
     <persistence>
         <entity>
             <class>org.apache.ambari.view.hive2.resources.jobs.viewJobs.JobImpl</class>


Mime
View raw message