Browse Source

AMBARI-16634. Ambari Admin Privilege required for Pig and Hive View. 403 error received when opening Pig View by a non-admin user. (Gaurav Nagar via dipayanb)

Dipayan Bhowmick 9 years ago
parent
commit
6ef093df1b

+ 16 - 0
ambari-server/src/main/java/org/apache/ambari/server/view/ClusterImpl.java

@@ -19,8 +19,13 @@
 package org.apache.ambari.server.view;
 
 import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.view.ClusterType;
 import org.apache.ambari.view.cluster.Cluster;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * View associated cluster implementation.
  */
@@ -58,4 +63,15 @@ public class ClusterImpl implements Cluster {
 
     return config == null ? null : config.getProperties().get(key);
   }
+
+  @Override
+  public List<String> getHostsForServiceComponent(String serviceName, String componentName){
+    List<ServiceComponentHost> serviceComponentHosts = cluster.getServiceComponentHosts(serviceName, componentName);
+    List<String> hosts = new ArrayList<String>();
+    for (ServiceComponentHost serviceComponentHost : serviceComponentHosts) {
+      hosts.add(serviceComponentHost.getHostName());
+    }
+    return hosts;
+  }
+
 }

+ 29 - 0
ambari-server/src/main/java/org/apache/ambari/server/view/RemoteAmbariCluster.java

@@ -120,6 +120,35 @@ public class RemoteAmbariCluster implements Cluster {
     return property.getAsJsonPrimitive().getAsString();
   }
 
+  @Override
+  public List<String> getHostsForServiceComponent(String serviceName, String componentName) {
+    String url = String.format("services/%s/components/%s?" +
+      "fields=host_components/HostRoles/host_name",serviceName,componentName);
+
+    List<String> hosts = new ArrayList<String>();
+
+    try {
+      JsonElement response = configurationCache.get(url);
+
+      if(response == null || !response.isJsonObject()) return hosts;
+
+      JsonElement hostComponents = response.getAsJsonObject().get("host_components");
+
+      if(hostComponents == null || !hostComponents.isJsonArray()) return hosts;
+
+      for (JsonElement element : hostComponents.getAsJsonArray()) {
+        JsonElement hostRoles = element.getAsJsonObject().get("HostRoles");
+        String hostName = hostRoles.getAsJsonObject().get("host_name").getAsString();
+        hosts.add(hostName);
+      }
+
+    } catch (ExecutionException e) {
+      throw new RemoteAmbariConfigurationReadException("Can't retrieve host information from Remote Ambari", e);
+    }
+
+    return hosts;
+  }
+
   /**
    * Get list of services installed on the remote cluster
    *

+ 34 - 0
ambari-server/src/test/java/org/apache/ambari/server/view/ClusterImplTest.java

@@ -20,11 +20,14 @@ package org.apache.ambari.server.view;
 
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.view.configuration.InstanceConfig;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import static org.easymock.EasyMock.createNiceMock;
@@ -73,4 +76,35 @@ public class ClusterImplTest {
 
     verify(cluster, config);
   }
+
+  @Test
+  public void testGetHostsForServiceComponent() {
+    Cluster cluster = createNiceMock(Cluster.class);
+
+    String service = "SERVICE";
+    String component = "COMPONENT";
+
+    List<ServiceComponentHost> components = new ArrayList<ServiceComponentHost>();
+
+    ServiceComponentHost component1 = createNiceMock(ServiceComponentHost.class);
+    expect(component1.getHostName()).andReturn("host1");
+    components.add(component1);
+
+    ServiceComponentHost component2 = createNiceMock(ServiceComponentHost.class);
+    expect(component2.getHostName()).andReturn("host2");
+    components.add(component2);
+
+    expect(cluster.getServiceComponentHosts(service,component)).andReturn(components);
+
+    replay(cluster, component1, component2);
+
+    ClusterImpl clusterImpl = new ClusterImpl(cluster);
+
+    List<String> hosts = clusterImpl.getHostsForServiceComponent(service,component);
+    Assert.assertEquals(2, hosts.size());
+    Assert.assertEquals("host1",hosts.get(0));
+    Assert.assertEquals("host2",hosts.get(1));
+
+    verify(cluster, component1, component2);
+  }
 }

+ 41 - 0
ambari-server/src/test/java/org/apache/ambari/server/view/RemoteAmbariClusterTest.java

@@ -19,14 +19,18 @@
 package org.apache.ambari.server.view;
 
 import org.apache.ambari.server.orm.entities.RemoteAmbariClusterEntity;
+import org.apache.ambari.view.AmbariHttpException;
 import org.apache.ambari.view.AmbariStreamProvider;
 import org.easymock.IAnswer;
+import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 import java.util.Map;
 
 import static org.easymock.EasyMock.anyObject;
@@ -35,6 +39,7 @@ import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.isNull;
 import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 
 public class RemoteAmbariClusterTest {
@@ -87,4 +92,40 @@ public class RemoteAmbariClusterTest {
     assertEquals(desiredConfigPolls[0], 1);  // cache hit
     assertEquals(testConfigPolls[0], 1);
   }
+
+  @Test
+  public void testGetHostsForServiceComponent() throws IOException, AmbariHttpException {
+
+    final String componentHostsString = "{\"host_components\": [{" +
+      "\"HostRoles\": {" +
+      "\"cluster_name\": \"Ambari\"," +
+      "\"host_name\": \"host1\"}}, {" +
+      "\"HostRoles\": {" +
+      "\"cluster_name\": \"Ambari\"," +
+      "\"host_name\": \"host2\"}}]}";
+
+    AmbariStreamProvider clusterStreamProvider = createNiceMock(AmbariStreamProvider.class);
+
+    String service = "SERVICE";
+    String component = "COMPONENT";
+
+    expect(clusterStreamProvider.readFrom(eq(String.format("services/%s/components/%s?" +
+        "fields=host_components/HostRoles/host_name",service,component)),
+      eq("GET"), (String) isNull(), (Map<String, String>) anyObject()))
+      .andReturn(new ByteArrayInputStream(componentHostsString.getBytes()));
+
+    RemoteAmbariClusterEntity entity = createNiceMock(RemoteAmbariClusterEntity.class);
+
+    replay(clusterStreamProvider,entity);
+
+    RemoteAmbariCluster cluster = new RemoteAmbariCluster("Test", clusterStreamProvider);
+
+    List<String> hosts = cluster.getHostsForServiceComponent(service,component);
+    Assert.assertEquals(2, hosts.size());
+    Assert.assertEquals("host1",hosts.get(0));
+    Assert.assertEquals("host2",hosts.get(1));
+
+    verify(clusterStreamProvider, entity);
+
+  }
 }

+ 11 - 0
ambari-views/src/main/java/org/apache/ambari/view/cluster/Cluster.java

@@ -18,6 +18,8 @@
 
 package org.apache.ambari.view.cluster;
 
+import java.util.List;
+
 /**
  * View associated cluster.  A cluster may be associated with a view instance so that the view instance may pull
  * configuration values from the cluster.
@@ -39,4 +41,13 @@ public interface Cluster {
    * @return the configuration value
    */
   public String getConfigurationValue(String type, String key);
+
+  /**
+   * Get the hosts for service and componet
+   *
+   * @param serviceName
+   * @param componentName
+   * @return list of hosts
+   */
+  public List<String> getHostsForServiceComponent(String serviceName, String componentName);
 }

+ 1 - 1
contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java

@@ -474,7 +474,7 @@ public class ConfigurationService {
   private String getRMHosts() {
     StringBuilder hosts = new StringBuilder();
     boolean first = true;
-    for (String host : ambariApi.getHostsWithComponent("RESOURCEMANAGER")) {
+    for (String host : context.getCluster().getHostsForServiceComponent("YARN", "RESOURCEMANAGER")) {
       if (!first) {
         hosts.append(",");
       }

+ 2 - 2
contrib/views/hive/src/main/java/org/apache/ambari/view/hive/client/ConnectionFactory.java

@@ -78,10 +78,10 @@ public class ConnectionFactory implements UserLocalFactory<Connection> {
   }
 
   private String getHiveHost() {
-    if (ambariApi.isClusterAssociated()) {
+    if (context.getCluster() != null) {
       List<String> hiveServerHosts;
       try {
-        hiveServerHosts = ambariApi.getHostsWithComponent("HIVE_SERVER");
+        hiveServerHosts = context.getCluster().getHostsForServiceComponent("HIVE","HIVE_SERVER");
       } catch (AmbariApiException e) {
         throw new ServiceFormattedException(e);
       }

+ 0 - 44
contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java

@@ -67,50 +67,6 @@ public class AmbariApi {
     this.requestedBy = requestedBy;
   }
 
-  /**
-   * Provides ability to get cluster topology
-   * @param requestComponent name of component
-   * @return list of hostnames with component
-   * @throws AmbariApiException
-   */
-  public List<String> getHostsWithComponent(String requestComponent) throws AmbariApiException {
-    String method = "hosts?fields=Hosts/public_host_name,host_components/HostRoles/component_name";
-    String response = requestClusterAPI(method);
-
-    List<String> foundHosts = new ArrayList<String>();
-
-    JSONObject jsonObject = (JSONObject) JSONValue.parse(response);
-    JSONArray hosts = (JSONArray) jsonObject.get("items");
-    for (Object host : hosts) {
-      JSONObject hostJson = (JSONObject) host;
-      JSONArray hostComponents = (JSONArray) hostJson.get("host_components");
-      for (Object component : hostComponents) {
-        JSONObject componentJson = (JSONObject) component;
-        JSONObject hostRoles = (JSONObject) componentJson.get("HostRoles");
-        String componentName = (String) hostRoles.get("component_name");
-        if (componentName.equals(requestComponent)) {
-          foundHosts.add((String) hostRoles.get("host_name"));
-        }
-      }
-    }
-    return foundHosts;
-  }
-
-  /**
-   * Returns first host with requested component installed
-   * @param requestComponent name of component
-   * @return any hostname of node that contains the component
-   * @throws AmbariApiException
-   */
-  public String getAnyHostWithComponent(String requestComponent) throws AmbariApiException {
-    List<String> foundHosts = getHostsWithComponent(requestComponent);
-
-    if (foundHosts.size() == 0) {
-      throw new AmbariApiException("RA100 Host with component " + requestComponent + " not found");
-    }
-    return foundHosts.get(0);
-  }
-
   /**
    * Shortcut for GET method
    * @param path REST API path

+ 1 - 1
contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java

@@ -217,7 +217,7 @@ public class Services {
     String host = null;
 
     if (context.getCluster() != null) {
-      List<String> hiveServerHosts = ambariApi.getHostsWithComponent("WEBHCAT_SERVER");
+      List<String> hiveServerHosts = context.getCluster().getHostsForServiceComponent("HIVE","WEBHCAT_SERVER");
 
       if (!hiveServerHosts.isEmpty()) {
         host = hiveServerHosts.get(0);