Browse Source

AMBARI-6739. Java side for BE work for download client configurations.

Mahadev Konar 10 years ago
parent
commit
989a4b9791
48 changed files with 1152 additions and 28 deletions
  1. 5 4
      ambari-common/src/main/python/resource_management/libraries/script/script.py
  2. 68 0
      ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClientConfigResourceDefinition.java
  3. 4 0
      ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
  4. 47 1
      ambari-server/src/main/java/org/apache/ambari/server/api/services/ComponentService.java
  5. 44 8
      ambari-server/src/main/java/org/apache/ambari/server/api/services/HostComponentService.java
  6. 4 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
  7. 14 0
      ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
  8. 2 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
  9. 423 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java
  10. 3 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
  11. 86 0
      ambari-server/src/main/java/org/apache/ambari/server/state/ClientConfigFileDefinition.java
  12. 16 0
      ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
  13. 6 0
      ambari-server/src/main/resources/key_properties.json
  14. 7 0
      ambari-server/src/main/resources/properties.json
  15. 12 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HBASE/metainfo.xml
  16. 12 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/metainfo.xml
  17. 12 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HIVE/metainfo.xml
  18. 17 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/metainfo.xml
  19. 12 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/OOZIE/metainfo.xml
  20. 7 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/PIG/metainfo.xml
  21. 7 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/SQOOP/metainfo.xml
  22. 7 0
      ambari-server/src/main/resources/stacks/HDP/1.3.2/services/ZOOKEEPER/metainfo.xml
  23. 12 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/metainfo.xml
  24. 12 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/metainfo.xml
  25. 15 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/metainfo.xml
  26. 12 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/metainfo.xml
  27. 8 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/metainfo.xml
  28. 7 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/SQOOP/metainfo.xml
  29. 34 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/metainfo.xml
  30. 7 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/ZOOKEEPER/metainfo.xml
  31. 13 0
      ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml
  32. 7 0
      ambari-server/src/main/resources/stacks/HDP/2.1/services/FALCON/metainfo.xml
  33. 12 0
      ambari-server/src/main/resources/stacks/HDP/2.1/services/TEZ/metainfo.xml
  34. 2 2
      ambari-server/src/test/java/org/apache/ambari/server/api/services/ComponentServiceTest.java
  35. 2 2
      ambari-server/src/test/java/org/apache/ambari/server/api/services/HostComponentServiceTest.java
  36. 146 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java
  37. 2 1
      ambari-server/src/test/python/stacks/1.3.2/HDFS/test_datanode.py
  38. 2 1
      ambari-server/src/test/python/stacks/1.3.2/HDFS/test_namenode.py
  39. 2 1
      ambari-server/src/test/python/stacks/1.3.2/HDFS/test_snamenode.py
  40. 2 1
      ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py
  41. 2 1
      ambari-server/src/test/python/stacks/2.0.6/HDFS/test_journalnode.py
  42. 3 0
      ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py
  43. 2 1
      ambari-server/src/test/python/stacks/2.0.6/HDFS/test_snamenode.py
  44. 2 1
      ambari-server/src/test/python/stacks/2.0.6/HDFS/test_zkfc.py
  45. 3 2
      ambari-server/src/test/python/stacks/2.0.6/configs/default.json
  46. 12 0
      ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HIVE/metainfo.xml
  47. 3 0
      ambari-server/src/test/resources/stacks/HDP/2.0.5/services/YARN/metainfo.xml
  48. 13 1
      ambari-server/src/test/resources/stacks/HDP/2.0.7/services/HIVE/metainfo.xml

+ 5 - 4
ambari-common/src/main/python/resource_management/libraries/script/script.py

@@ -243,11 +243,11 @@ class Script(object):
     based on xml_configs_list and env_configs_list from commandParams
     """
     import params
-    config = self.get_config()
-    xml_configs_list = json.loads(config['commandParams']['xml_configs_list'])
-    env_configs_list = json.loads(config['commandParams']['env_configs_list'])
+    env.set_params(params)
+    xml_configs_list = params.config['commandParams']['xml_configs_list']
+    env_configs_list = params.config['commandParams']['env_configs_list']
     conf_tmp_dir = tempfile.mkdtemp()
-    output_filename = os.path.join(self.get_tmp_dir(),"client-configs.tar.gz")
+    output_filename = os.path.join(self.get_tmp_dir(),params.config['commandParams']['output_file'])
 
     Directory(self.get_tmp_dir(), recursive=True)
     for file_dict in xml_configs_list:
@@ -264,4 +264,5 @@ class Script(object):
         )
     with closing(tarfile.open(output_filename, "w:gz")) as tar:
       tar.add(conf_tmp_dir, arcname=os.path.basename("."))
+      tar.close()
     Directory(conf_tmp_dir, action="delete")

+ 68 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClientConfigResourceDefinition.java

@@ -0,0 +1,68 @@
+/**
+ * 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.server.api.resources;
+
+import org.apache.ambari.server.api.query.render.ClusterBlueprintRenderer;
+import org.apache.ambari.server.api.query.render.DefaultRenderer;
+import org.apache.ambari.server.api.query.render.MinimalRenderer;
+import org.apache.ambari.server.api.query.render.Renderer;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import java.util.Collection;
+
+
+/**
+ * Blueprint resource definition.
+ */
+public class ClientConfigResourceDefinition extends BaseResourceDefinition {
+  /**
+   * Constructor.
+   *
+   */
+  public ClientConfigResourceDefinition() {
+    super(Resource.Type.ClientConfig);
+  }
+
+  @Override
+  public String getPluralName() {
+    return "configurations";
+  }
+
+  @Override
+  public String getSingularName() {
+    return "configuration";
+  }
+
+  @Override
+  public Renderer getRenderer(String name) {
+    if (name != null && name.equals("client_config_tar")) {
+      return new DefaultRenderer();
+    } else {
+      return super.getRenderer(name);
+    }
+  }
+
+  @Override
+  public Collection<String> getCreateDirectives() {
+    Collection<String> directives = super.getCreateDirectives();
+    directives.add("validate_topology");
+
+    return directives;
+  }
+}

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java

@@ -271,6 +271,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
         resourceDefinition = new ControllerResourceDefinition(
             ControllerType.getByName(mapIds.get(Resource.Type.Controller)));
 
+      case ClientConfig:
+        resourceDefinition = new ClientConfigResourceDefinition();
+        break;
+
       default:
         throw new IllegalArgumentException("Unsupported resource type: " + type);
     }

+ 47 - 1
ambari-server/src/main/java/org/apache/ambari/server/api/services/ComponentService.java

@@ -18,11 +18,20 @@
 
 package org.apache.ambari.server.api.services;
 
+import com.google.inject.Inject;
 import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.ClusterController;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.state.ConfigHelper;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -64,7 +73,10 @@ public class ComponentService extends BaseService {
   @Path("{componentName}")
   @Produces("text/plain")
   public Response getComponent(String body, @Context HttpHeaders headers, @Context UriInfo ui,
-                               @PathParam("componentName") String componentName) {
+                               @PathParam("componentName") String componentName, @QueryParam("format") String format) {
+    if (format != null && format.equals("client_config_tar")) {
+      return createClientConfigResource(body, headers, ui, componentName);
+    }
 
     return handleRequest(headers, body, ui, Request.Type.GET,
         createComponentResource(m_clusterName, m_serviceName, componentName));
@@ -201,4 +213,38 @@ public class ComponentService extends BaseService {
 
     return createResource(Resource.Type.Component, mapIds);
   }
+
+  private Response createClientConfigResource(String body, HttpHeaders headers, UriInfo ui,
+                                      String componentName) {
+    Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+    mapIds.put(Resource.Type.Cluster, m_clusterName);
+    mapIds.put(Resource.Type.Service, m_serviceName);
+    mapIds.put(Resource.Type.Component, componentName);
+
+
+    Response response = handleRequest(headers, body, ui, Request.Type.GET,
+            createResource(Resource.Type.ClientConfig, mapIds));
+
+    //If response has errors return response
+    if (response.getStatus() != 200) {
+      return response;
+    }
+
+    Response.ResponseBuilder rb = Response.status(Response.Status.OK);
+    File file = new File("/tmp/ambari-server/"+componentName+"-configs.tar.gz");
+    InputStream resultInputStream = null;
+    try {
+      resultInputStream = new FileInputStream(file);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    String contentType = "application/x-ustar";
+    String outputFileName = componentName + "-configs.tar.gz";
+    rb.header("Content-Disposition",  "attachment; filename=\"" + outputFileName + "\"");
+    rb.entity(resultInputStream);
+    return rb.type(contentType).build();
+
+  }
+
 }

+ 44 - 8
ambari-server/src/main/java/org/apache/ambari/server/api/services/HostComponentService.java

@@ -18,16 +18,14 @@
 
 package org.apache.ambari.server.api.services;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
+import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
@@ -74,7 +72,7 @@ public class HostComponentService extends BaseService {
   @Path("{hostComponentName}")
   @Produces("text/plain")
   public Response getHostComponent(String body, @Context HttpHeaders headers, @Context UriInfo ui,
-                                   @PathParam("hostComponentName") String hostComponentName) {
+                                   @PathParam("hostComponentName") String hostComponentName, @QueryParam("format") String format) {
 
     //todo: needs to be refactored when properly handling exceptions
     if (m_hostName == null) {
@@ -83,6 +81,10 @@ public class HostComponentService extends BaseService {
       return Response.status(400).entity(s).build();
     }
 
+    if (format != null && format.equals("client_config_tar")) {
+      return createClientConfigResource(body, headers, ui, hostComponentName);
+    }
+
     return handleRequest(headers, body, ui, Request.Type.GET,
         createHostComponentResource(m_clusterName, m_hostName, hostComponentName));
   }
@@ -250,4 +252,38 @@ public class HostComponentService extends BaseService {
 
     return createResource(Resource.Type.HostComponent, mapIds);
   }
+
+  private Response createClientConfigResource(String body, HttpHeaders headers, UriInfo ui,
+                                              String hostComponentName) {
+    Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+    mapIds.put(Resource.Type.Cluster, m_clusterName);
+    mapIds.put(Resource.Type.Host, m_hostName);
+    mapIds.put(Resource.Type.Component, hostComponentName);
+
+
+    Response response = handleRequest(headers, body, ui, Request.Type.GET,
+            createResource(Resource.Type.ClientConfig, mapIds));
+
+    //If response has errors return response
+    if (response.getStatus() != 200) {
+      return response;
+    }
+
+    Response.ResponseBuilder rb = Response.status(Response.Status.OK);
+    File file = new File("/tmp/ambari-server/"+hostComponentName+"-configs.tar.gz");
+    InputStream resultInputStream = null;
+    try {
+      resultInputStream = new FileInputStream(file);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    String contentType = "application/x-ustar";
+    String outputFileName = hostComponentName + "-configs.tar.gz";
+    rb.header("Content-Disposition",  "attachment; filename=\"" + outputFileName + "\"");
+    rb.entity(resultInputStream);
+    return rb.type(contentType).build();
+
+  }
+
 }

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java

@@ -23,6 +23,10 @@ import org.apache.ambari.server.controller.spi.Resource;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 

+ 14 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java

@@ -304,6 +304,20 @@ public class StackExtensionHelper {
     result.setConfigDependencies(
         child.getConfigDependencies() != null ?
             child.getConfigDependencies() : parent.getConfigDependencies());
+
+//    HashSet downloadSource = child.getDownloadSource();
+//    if (downloadSource != null) {
+//      result.setDownloadSource(child.getDownloadSource());
+//    } else {
+//      result.setDownloadSource(parent.getDownloadSource());
+//    }
+//
+    List<ClientConfigFileDefinition> clientConfigFiles = child.getClientConfigFiles();
+    if (clientConfigFiles != null) {
+      result.setClientConfigFiles(child.getClientConfigFiles());
+    } else {
+      result.setClientConfigFiles(parent.getClientConfigFiles());
+    }
     // Merge custom command definitions for service
     List<CustomCommandDefinition> mergedCustomCommands =
                 mergeCustomCommandLists(parent.getCustomCommands(),

+ 2 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java

@@ -154,6 +154,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
         return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
       case Controller:
         return new ControllerResourceProvider(propertyIds, keyPropertyIds, managementController);
+      case ClientConfig:
+        return new ClientConfigResourceProvider(propertyIds, keyPropertyIds, managementController);
       default:
         throw new IllegalArgumentException("Unknown type " + type);
     }

+ 423 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProvider.java

@@ -0,0 +1,423 @@
+/**
+ * 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.server.controller.internal;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import com.google.inject.persist.Transactional;
+import org.apache.ambari.server.*;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.*;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.utils.StageUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.*;
+
+/**
+ * Resource provider for client config resources.
+ */
+public class ClientConfigResourceProvider extends AbstractControllerResourceProvider {
+
+
+  // ----- Property ID constants ---------------------------------------------
+
+  protected static final String COMPONENT_CLUSTER_NAME_PROPERTY_ID = "ServiceComponentInfo/cluster_name";
+  protected static final String COMPONENT_SERVICE_NAME_PROPERTY_ID = "ServiceComponentInfo/service_name";
+  protected static final String COMPONENT_COMPONENT_NAME_PROPERTY_ID = "ServiceComponentInfo/component_name";
+  protected static final String HOST_COMPONENT_HOST_NAME_PROPERTY_ID =
+          PropertyHelper.getPropertyId("HostRoles", "host_name");
+  protected static final String TMP_PATH = "/tmp/ambari-server";
+
+  private final Gson gson;
+
+  private static Set<String> pkPropertyIds =
+          new HashSet<String>(Arrays.asList(new String[]{
+                  COMPONENT_CLUSTER_NAME_PROPERTY_ID,
+                  COMPONENT_SERVICE_NAME_PROPERTY_ID,
+                  COMPONENT_COMPONENT_NAME_PROPERTY_ID}));
+
+  private MaintenanceStateHelper maintenanceStateHelper;
+
+  // ----- Constructors ----------------------------------------------------
+
+  /**
+   * Create a  new resource provider for the given management controller.
+   *
+   * @param propertyIds          the property ids
+   * @param keyPropertyIds       the key property ids
+   * @param managementController the management controller
+   */
+  @AssistedInject
+  ClientConfigResourceProvider(@Assisted Set<String> propertyIds,
+                               @Assisted Map<Resource.Type, String> keyPropertyIds,
+                               @Assisted AmbariManagementController managementController) {
+    super(propertyIds, keyPropertyIds, managementController);
+    gson = new Gson();
+  }
+
+  // ----- ResourceProvider ------------------------------------------------
+
+  @Override
+  public RequestStatus createResources(Request request)
+          throws SystemException,
+          UnsupportedPropertyException,
+          ResourceAlreadyExistsException,
+          NoSuchParentResourceException {
+
+    throw new SystemException("The request is not supported");
+  }
+
+  @Override
+  @Transactional
+  public Set<Resource> getResources(Request request, Predicate predicate)
+          throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    Set<Resource> resources = new HashSet<Resource>();
+
+    final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+      requests.add(getRequest(propertyMap));
+    }
+
+    Set<ServiceComponentHostResponse> responses = null;
+    try {
+      responses = getResources(new Command<Set<ServiceComponentHostResponse>>() {
+        @Override
+        public Set<ServiceComponentHostResponse> invoke() throws AmbariException {
+          return getManagementController().getHostComponents(requests);
+        }
+      });
+    } catch (Exception e) {
+      throw new SystemException("Failed to get components ", e);
+    }
+
+    AmbariManagementController managementController = getManagementController();
+    ConfigHelper configHelper = managementController.getConfigHelper();
+    Cluster cluster = null;
+    Clusters clusters = managementController.getClusters();
+    try {
+      cluster = clusters.getCluster(responses.iterator().next().getClusterName());
+
+      StackId stackId = cluster.getCurrentStackVersion();
+      String serviceName = responses.iterator().next().getServiceName();
+      String componentName = responses.iterator().next().getComponentName();
+      String hostName = responses.iterator().next().getHostname();
+      ComponentInfo componentInfo = null;
+      String packageFolder = null;
+
+      componentInfo = managementController.getAmbariMetaInfo().
+              getComponent(stackId.getStackName(), stackId.getStackVersion(), serviceName, componentName);
+      packageFolder = managementController.getAmbariMetaInfo().
+              getServiceInfo(stackId.getStackName(), stackId.getStackVersion(), serviceName).getServicePackageFolder();
+
+      String commandScript = componentInfo.getCommandScript().getScript();
+      List<ClientConfigFileDefinition> clientConfigFiles = componentInfo.getClientConfigFiles();
+
+      if (clientConfigFiles == null) {
+        throw new SystemException("No cofiguration files defined for the component");
+      }
+
+      String stackRoot = managementController.getAmbariMetaInfo().getStackRoot().getAbsolutePath();
+
+      String packageFolderAbsolute = stackRoot + File.separator + packageFolder;
+      String commandScriptAbsolute = packageFolderAbsolute + File.separator + commandScript;
+
+
+      Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
+      Map<String, Map<String, Map<String, String>>> configurationAttributes = new TreeMap<String, Map<String, Map<String, String>>>();
+
+      Collection<Config> clusterConfigs = cluster.getAllConfigs();
+
+      //Get configurations and configuration attributes
+      for (Config clusterConfig : clusterConfigs) {
+
+        if (clusterConfig != null) {
+          Map<String, String> props = new HashMap<String, String>(clusterConfig.getProperties());
+
+          // Apply global properties for this host from all config groups
+          Map<String, Map<String, String>> allConfigTags = null;
+          allConfigTags = configHelper
+                  .getEffectiveDesiredTags(cluster, hostName);
+
+          Map<String, Map<String, String>> configTags = new HashMap<String,
+                  Map<String, String>>();
+
+          for (Map.Entry<String, Map<String, String>> entry : allConfigTags.entrySet()) {
+            if (entry.getKey().equals(clusterConfig.getType())) {
+              configTags.put(clusterConfig.getType(), entry.getValue());
+            }
+          }
+
+          Map<String, Map<String, String>> properties = configHelper
+                  .getEffectiveConfigProperties(cluster, configTags);
+
+          if (!properties.isEmpty()) {
+            for (Map<String, String> propertyMap : properties.values()) {
+              props.putAll(propertyMap);
+            }
+          }
+
+          configurations.put(clusterConfig.getType(), props);
+
+          Map<String, Map<String, String>> attrs = new TreeMap<String, Map<String, String>>();
+          configHelper.cloneAttributesMap(clusterConfig.getPropertiesAttributes(), attrs);
+
+          Map<String, Map<String, Map<String, String>>> attributes = configHelper
+                  .getEffectiveConfigAttributes(cluster, configTags);
+          for (Map<String, Map<String, String>> attributesMap : attributes.values()) {
+            configHelper.cloneAttributesMap(attributesMap, attrs);
+          }
+          configurationAttributes.put(clusterConfig.getType(), attrs);
+        }
+      }
+
+      Map<String, Set<String>> clusterHostInfo = null;
+      ServiceInfo serviceInfo = null;
+      String osFamily = null;
+      clusterHostInfo = StageUtils.getClusterHostInfo(managementController.getClusters().getHostsForCluster(cluster.getClusterName()), cluster);
+      serviceInfo = managementController.getAmbariMetaInfo().getServiceInfo(stackId.getStackName(),
+              stackId.getStackVersion(), serviceName);
+      osFamily = clusters.getHost(hostName).getOsFamily();
+
+      TreeMap<String, String> hostLevelParams = new TreeMap<String, String>();
+      hostLevelParams.put(JDK_LOCATION, managementController.getJdkResourceUrl());
+      hostLevelParams.put(JAVA_HOME, managementController.getJavaHome());
+      hostLevelParams.put(JDK_NAME, managementController.getJDKName());
+      hostLevelParams.put(JCE_NAME, managementController.getJCEName());
+      hostLevelParams.put(STACK_NAME, stackId.getStackName());
+      hostLevelParams.put(STACK_VERSION, stackId.getStackVersion());
+      hostLevelParams.put(DB_NAME, managementController.getServerDB());
+      hostLevelParams.put(MYSQL_JDBC_URL, managementController.getMysqljdbcUrl());
+      hostLevelParams.put(ORACLE_JDBC_URL, managementController.getOjdbcUrl());
+      hostLevelParams.putAll(managementController.getRcaParameters());
+      hostLevelParams.putAll(managementController.getRcaParameters());
+
+      // Write down os specific info for the service
+      ServiceOsSpecific anyOs = null;
+      if (serviceInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) {
+        anyOs = serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS);
+      }
+
+      ServiceOsSpecific hostOs = populateServicePackagesInfo(serviceInfo, hostLevelParams, osFamily);
+
+      // Build package list that is relevant for host
+      List<ServiceOsSpecific.Package> packages =
+              new ArrayList<ServiceOsSpecific.Package>();
+      if (anyOs != null) {
+        packages.addAll(anyOs.getPackages());
+      }
+
+      if (hostOs != null) {
+        packages.addAll(hostOs.getPackages());
+      }
+      String packageList = gson.toJson(packages);
+      hostLevelParams.put(PACKAGE_LIST, packageList);
+
+      String jsonConfigurations = null;
+      Map<String, Object> commandParams = new HashMap<String, Object>();
+      List<Map<String, String>> xmlConfigs = new LinkedList<Map<String, String>>();
+      List<Map<String, String>> envConfigs = new LinkedList<Map<String, String>>();
+
+      //Fill file-dictionary configs from metainfo
+      for (ClientConfigFileDefinition clientConfigFile : clientConfigFiles) {
+        Map<String, String> fileDict = new HashMap<String, String>();
+        fileDict.put(clientConfigFile.getFileName(), clientConfigFile.getDictionaryName());
+        if (clientConfigFile.getType().equals("xml")) {
+          xmlConfigs.add(fileDict);
+        } else {
+          envConfigs.add(fileDict);
+        }
+      }
+
+      commandParams.put("xml_configs_list", xmlConfigs);
+      commandParams.put("env_configs_list", envConfigs);
+      commandParams.put("output_file", componentName + "-configs.tar.gz");
+
+      Map<String, Object> jsonContent = new TreeMap<String, Object>();
+      jsonContent.put("configurations", configurations);
+      jsonContent.put("configuration_attributes", configurationAttributes);
+      jsonContent.put("commandParams", commandParams);
+      jsonContent.put("clusterHostInfo", clusterHostInfo);
+      jsonContent.put("hostLevelParams", hostLevelParams);
+      jsonContent.put("hostname", hostName);
+      jsonConfigurations = gson.toJson(jsonContent);
+
+      File jsonFileName = new File(TMP_PATH + File.separator + componentName + "-configuration.json");
+      File tmpDirectory = new File(jsonFileName.getParent());
+      if (!tmpDirectory.exists()) {
+        try {
+          tmpDirectory.mkdir();
+          tmpDirectory.setWritable(true, true);
+          tmpDirectory.setReadable(true, true);
+        } catch (SecurityException se) {
+          throw new SystemException("Failed to get temporary directory to store configurations", se);
+        }
+      }
+      PrintWriter printWriter = null;
+      try {
+        printWriter = new PrintWriter(jsonFileName.getAbsolutePath());
+        printWriter.print(jsonConfigurations);
+        printWriter.close();
+      } catch (FileNotFoundException e) {
+        throw new SystemException("Failed to write configurations to json file ", e);
+      }
+
+      String cmd = "python " + commandScriptAbsolute + " generate_configs " + jsonFileName.getAbsolutePath() + " " +
+              packageFolderAbsolute + " " + TMP_PATH + File.separator + "structured-out.json" + " INFO " + TMP_PATH;
+
+      try {
+        executeCommand(cmd, 1500);
+      } catch (TimeoutException e) {
+        throw new SystemException("Script was killed due to timeout  ", e);
+      } catch (Exception e) {
+        throw new SystemException("Failed to run python script for a component ", e);
+      }
+
+    } catch (AmbariException e) {
+      throw new SystemException("Controller error ", e);
+    }
+
+    return resources;
+  }
+
+  @Override
+  public RequestStatus updateResources(final Request request, Predicate predicate)
+          throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    throw new SystemException("The request is not supported");
+  }
+
+  @Override
+  public RequestStatus deleteResources(Predicate predicate)
+          throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    throw new SystemException("The request is not supported");
+  }
+
+
+  // ----- AbstractResourceProvider ------------------------------------------
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return pkPropertyIds;
+  }
+
+
+  // ----- utility methods ---------------------------------------------------
+
+  /**
+   * Get a component request object from a map of property values.
+   *
+   * @param properties the predicate
+   * @return the component request object
+   */
+
+  private ServiceComponentHostRequest getRequest(Map<String, Object> properties) {
+    return new ServiceComponentHostRequest(
+            (String) properties.get(COMPONENT_CLUSTER_NAME_PROPERTY_ID),
+            (String) properties.get(COMPONENT_SERVICE_NAME_PROPERTY_ID),
+            (String) properties.get(COMPONENT_COMPONENT_NAME_PROPERTY_ID),
+            (String) properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
+            null);
+  }
+
+
+  private static int executeCommand(final String commandLine,
+                                    final long timeout)
+          throws IOException, InterruptedException, TimeoutException {
+    Runtime runtime = Runtime.getRuntime();
+    Process process = runtime.exec(commandLine);
+    CommandLineThread commandLineThread = new CommandLineThread(process);
+    commandLineThread.start();
+    try {
+      commandLineThread.join(timeout);
+      if (commandLineThread.exit != null)
+        return commandLineThread.exit;
+      else
+        throw new TimeoutException();
+    } catch (InterruptedException ex) {
+      commandLineThread.interrupt();
+      Thread.currentThread().interrupt();
+      throw ex;
+    } finally {
+      process.destroy();
+    }
+  }
+
+  private static class CommandLineThread extends Thread {
+    private final Process process;
+    private Integer exit;
+
+    private CommandLineThread(Process process) {
+      this.process = process;
+    }
+
+
+    public void run() {
+      try {
+        exit = process.waitFor();
+      } catch (InterruptedException ignore) {
+        return;
+      }
+    }
+  }
+
+  protected ServiceOsSpecific populateServicePackagesInfo(ServiceInfo serviceInfo, Map<String, String> hostParams,
+                                                          String osFamily) {
+    ServiceOsSpecific hostOs = new ServiceOsSpecific(osFamily);
+    List<ServiceOsSpecific> foundedOSSpecifics = getOSSpecificsByFamily(serviceInfo.getOsSpecifics(), osFamily);
+    if (!foundedOSSpecifics.isEmpty()) {
+      for (ServiceOsSpecific osSpecific : foundedOSSpecifics) {
+        hostOs.addPackages(osSpecific.getPackages());
+      }
+      // Choose repo that is relevant for host
+      ServiceOsSpecific.Repo serviceRepo = hostOs.getRepo();
+      if (serviceRepo != null) {
+        String serviceRepoInfo = gson.toJson(serviceRepo);
+        hostParams.put(SERVICE_REPO_INFO, serviceRepoInfo);
+      }
+    }
+
+    return hostOs;
+  }
+
+  private List<ServiceOsSpecific> getOSSpecificsByFamily(Map<String, ServiceOsSpecific> osSpecifics, String osFamily) {
+    List<ServiceOsSpecific> foundedOSSpecifics = new ArrayList<ServiceOsSpecific>();
+    for (Map.Entry<String, ServiceOsSpecific> osSpecific : osSpecifics.entrySet()) {
+      if (osSpecific.getKey().indexOf(osFamily) != -1) {
+        foundedOSSpecifics.add(osSpecific.getValue());
+      }
+    }
+    return foundedOSSpecifics;
+  }
+
+}

+ 3 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java

@@ -119,7 +119,8 @@ public interface Resource {
     ClusterPrivilege,
     ViewPrivilege,
     ViewPermission,
-    Controller;
+    Controller,
+    ClientConfig;
 
     /**
      * Get the {@link Type} that corresponds to this InternalType.
@@ -200,6 +201,7 @@ public interface Resource {
     public static final Type ViewPrivilege = InternalType.ViewPrivilege.getType();
     public static final Type ViewPermission = InternalType.ViewPermission.getType();
     public static final Type Controller = InternalType.Controller.getType();
+    public static final Type ClientConfig = InternalType.ClientConfig.getType();
 
     /**
      * The type name.

+ 86 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/ClientConfigFileDefinition.java

@@ -0,0 +1,86 @@
+/**
+ * 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.server.state;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+/**
+ * Represents the configFiles tag at service/component metainfo
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ClientConfigFileDefinition {
+
+  private String type;
+  private String fileName;
+  private String dictionaryName;
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public String getFileName() {
+    return fileName;
+  }
+
+  public void setFileName(String fileName) {
+    this.fileName = fileName;
+  }
+
+  public String getDictionaryName() {
+    return dictionaryName;
+  }
+
+  public void setDictionaryName(String dictionaryName) {
+    this.dictionaryName = dictionaryName;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (obj == this) {
+      return true;
+    }
+    if (! (obj instanceof ClientConfigFileDefinition)) {
+      return false;
+    }
+
+    ClientConfigFileDefinition rhs = (ClientConfigFileDefinition) obj;
+    return new EqualsBuilder().
+            append(type, rhs.type).
+            append(fileName, rhs.fileName).
+            append(dictionaryName, rhs.dictionaryName).isEquals();
+  }
+
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder(17, 31).
+            append(type).
+            append(fileName).
+            append(dictionaryName).toHashCode();
+  }
+}

+ 16 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java

@@ -39,6 +39,13 @@ public class ComponentInfo {
   */
   private CommandScriptDefinition commandScript;
 
+  /**
+   *
+   */
+  @XmlElementWrapper(name = "configFiles")
+  @XmlElements(@XmlElement(name = "configFile"))
+  private List<ClientConfigFileDefinition> clientConfigFiles;
+
   /**
    * Added at schema ver 2
    */
@@ -77,6 +84,7 @@ public class ComponentInfo {
     dependencies = prototype.dependencies;
     autoDeploy = prototype.autoDeploy;
     configDependencies = prototype.configDependencies;
+    clientConfigFiles = prototype.clientConfigFiles;
   }
 
   public String getName() {
@@ -119,6 +127,14 @@ public class ComponentInfo {
     this.commandScript = commandScript;
   }
 
+  public List<ClientConfigFileDefinition> getClientConfigFiles() {
+    return clientConfigFiles;
+  }
+
+  public void setClientConfigFiles(List<ClientConfigFileDefinition> clientConfigFiles) {
+    this.clientConfigFiles = clientConfigFiles;
+  }
+
   public List<CustomCommandDefinition> getCustomCommands() {
     if (customCommands == null) {
       customCommands = new ArrayList<CustomCommandDefinition>();

+ 6 - 0
ambari-server/src/main/resources/key_properties.json

@@ -151,5 +151,11 @@
   },
   "Controller": {
     "Controller": "Controllers/name"
+  },
+  "ClientConfig": {
+    "Cluster": "ServiceComponentInfo/cluster_name",
+    "Service": "ServiceComponentInfo/service_name",
+    "Component": "ServiceComponentInfo/component_name",
+    "Host": "HostRoles/host_name"
   }
 }

+ 7 - 0
ambari-server/src/main/resources/properties.json

@@ -426,5 +426,12 @@
         "LDAP/synced_users",
         "LDAP/synced_groups",
         "_"
+    ],
+    "ClientConfig":[
+        "ServiceComponentInfo/service_name",
+        "ServiceComponentInfo/component_name",
+        "ServiceComponentInfo/cluster_name",
+        "HostRoles/host_name",
+        "_"
     ]
 }

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HBASE/metainfo.xml

@@ -91,6 +91,18 @@
             <script>scripts/hbase_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hbase-site.xml</fileName>
+              <dictionaryName>hbase-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hbase-env.sh</fileName>
+              <dictionaryName>hbase-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HDFS/metainfo.xml

@@ -76,6 +76,18 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hdfs-site.xml</fileName>
+              <dictionaryName>hdfs-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hdfs-env.sh</fileName>
+              <dictionaryName>hdfs-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
       <osSpecifics>

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/HIVE/metainfo.xml

@@ -84,6 +84,18 @@
             <script>scripts/hive_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hive-site.xml</fileName>
+              <dictionaryName>hive-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hive-env.sh</fileName>
+              <dictionaryName>hive-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 17 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/MAPREDUCE/metainfo.xml

@@ -65,6 +65,23 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>core-site.xml</fileName>
+              <dictionaryName>core-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>xml</type>
+              <fileName>mapred-site.xml</fileName>
+              <dictionaryName>mapred-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>mapred-env.sh</fileName>
+              <dictionaryName>mapred-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
               
         <component>

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/OOZIE/metainfo.xml

@@ -75,6 +75,18 @@
             <script>scripts/oozie_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>oozie-site.xml</fileName>
+              <dictionaryName>oozie-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>oozie-env.sh</fileName>
+              <dictionaryName>oozie-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/PIG/metainfo.xml

@@ -32,6 +32,13 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>pig-env.sh</fileName>
+              <dictionaryName>pig-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
       <osSpecifics>

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/SQOOP/metainfo.xml

@@ -50,6 +50,13 @@
             <script>scripts/sqoop_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>sqoop-env.sh</fileName>
+              <dictionaryName>sqoop-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
       <osSpecifics>

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/1.3.2/services/ZOOKEEPER/metainfo.xml

@@ -43,6 +43,13 @@
             <script>scripts/zookeeper_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>zookeeper-env.sh</fileName>
+              <dictionaryName>zookeeper-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/metainfo.xml

@@ -81,6 +81,18 @@
             <script>scripts/hbase_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hbase-site.xml</fileName>
+              <dictionaryName>hbase-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hbase-env.sh</fileName>
+              <dictionaryName>hbase-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/metainfo.xml

@@ -77,6 +77,18 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hdfs-site.xml</fileName>
+              <dictionaryName>hdfs-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hadoop-env.sh</fileName>
+              <dictionaryName>hadoop-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
 
         <component>

+ 15 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/metainfo.xml

@@ -91,6 +91,18 @@
             <script>scripts/hive_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hive-site.xml</fileName>
+              <dictionaryName>hive-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hive-env.sh</fileName>
+              <dictionaryName>hive-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 
@@ -157,6 +169,9 @@
             <script>scripts/hcat_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <downloads>
+            <source>/etc/hcatalog/conf</source>
+          </downloads>
         </component>
       </components>
       <osSpecifics>

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/metainfo.xml

@@ -82,6 +82,18 @@
             <script>scripts/oozie_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>oozie-site.xml</fileName>
+              <dictionaryName>oozie-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>oozie-env.sh</fileName>
+              <dictionaryName>oozie-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 8 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/metainfo.xml

@@ -51,6 +51,14 @@
         <timeout>300</timeout>
       </commandScript>
 
+      <configFiles>
+        <configFile>
+          <type>env</type>
+          <fileName>pig-env.sh</fileName>
+          <dictionaryName>pig-env</dictionaryName>
+        </configFile>
+      </configFiles>
+
       <configuration-dependencies>
         <config-type>pig-env</config-type>
         <config-type>pig-log4j</config-type>

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/SQOOP/metainfo.xml

@@ -50,6 +50,13 @@
             <script>scripts/sqoop_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>sqoop-env.sh</fileName>
+              <dictionaryName>sqoop-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
       <osSpecifics>

+ 34 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/metainfo.xml

@@ -77,6 +77,23 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>yarn-site.xml</fileName>
+              <dictionaryName>yarn-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>xml</type>
+              <fileName>core-site.xml</fileName>
+              <dictionaryName>core-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>yarn-env.sh</fileName>
+              <dictionaryName>yarn-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 
@@ -148,6 +165,23 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>yarn-site.xml</fileName>
+              <dictionaryName>yarn-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>xml</type>
+              <fileName>core-site.xml</fileName>
+              <dictionaryName>core-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>yarn-env.sh</fileName>
+              <dictionaryName>yarn-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/ZOOKEEPER/metainfo.xml

@@ -43,6 +43,13 @@
             <script>scripts/zookeeper_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>zookeeper-env.sh</fileName>
+              <dictionaryName>zookeeper-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 13 - 0
ambari-server/src/main/resources/stacks/HDP/2.1.GlusterFS/services/HIVE/metainfo.xml

@@ -36,6 +36,19 @@
       <name>HCATALOG</name>
       <comment>This is comment for HCATALOG service</comment>
       <version>0.12.0.2.1</version>
+      <components>
+        <component>
+          <name>HCAT</name>
+          <category>CLIENT</category>
+          <commandScript>
+            <script>scripts/hcat_client.py</script>
+            <scriptType>PYTHON</scriptType>
+          </commandScript>
+          <downloads>
+            <source>/etc/hive-hcatalog/conf</source>
+          </downloads>
+        </component>
+      </components>
       <osSpecifics>
         <osSpecific>
           <osFamily>any</osFamily>

+ 7 - 0
ambari-server/src/main/resources/stacks/HDP/2.1/services/FALCON/metainfo.xml

@@ -32,6 +32,13 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>falcon-env.sh</fileName>
+              <dictionaryName>falcon-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
         <component>
           <name>FALCON_SERVER</name>

+ 12 - 0
ambari-server/src/main/resources/stacks/HDP/2.1/services/TEZ/metainfo.xml

@@ -32,6 +32,18 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>tez-site.xml</fileName>
+              <dictionaryName>tez-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>tez-env.sh</fileName>
+              <dictionaryName>tez-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
       <osSpecifics>

+ 2 - 2
ambari-server/src/test/java/org/apache/ambari/server/api/services/ComponentServiceTest.java

@@ -43,8 +43,8 @@ public class ComponentServiceTest extends BaseServiceTest {
 
     //getComponent
     ComponentService service = new TestComponentService("clusterName", "serviceName", "componentName");
-    Method m = service.getClass().getMethod("getComponent", String.class, HttpHeaders.class, UriInfo.class, String.class);
-    Object[] args = new Object[] {null, getHttpHeaders(), getUriInfo(), "componentName"};
+    Method m = service.getClass().getMethod("getComponent", String.class, HttpHeaders.class, UriInfo.class, String.class, String.class);
+    Object[] args = new Object[] {null, getHttpHeaders(), getUriInfo(), "componentName", null};
     listInvocations.add(new ServiceTestInvocation(Request.Type.GET, service, m, args, null));
 
     //getComponents

+ 2 - 2
ambari-server/src/test/java/org/apache/ambari/server/api/services/HostComponentServiceTest.java

@@ -42,8 +42,8 @@ public class HostComponentServiceTest extends BaseServiceTest {
 
     //getHostComponent
     HostComponentService componentService = new TestHostComponentService("clusterName", "serviceName", "componentName");
-    Method m = componentService.getClass().getMethod("getHostComponent", String.class, HttpHeaders.class, UriInfo.class, String.class);
-    Object[] args = new Object[] {null, getHttpHeaders(), getUriInfo(), "componentName"};
+    Method m = componentService.getClass().getMethod("getHostComponent", String.class, HttpHeaders.class, UriInfo.class, String.class, String.class);
+    Object[] args = new Object[]{null, getHttpHeaders(), getUriInfo(), "componentName", null};
     listInvocations.add(new ServiceTestInvocation(Request.Type.GET, componentService, m, args, null));
 
     //getHostComponents

+ 146 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClientConfigResourceProviderTest.java

@@ -0,0 +1,146 @@
+/**
+ * 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.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.TaskStatusResponse;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * TaskResourceProvider tests.
+ */
+public class ClientConfigResourceProviderTest {
+  @Test
+  public void testCreateResources() throws Exception {
+    Resource.Type type = Resource.Type.ClientConfig;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.  add more maps for multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
+
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // add properties to the request map
+    properties.put(ClientConfigResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID, "c1");
+    properties.put(ClientConfigResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID, "HDFS_CLIENT");
+    properties.put(ClientConfigResourceProvider.COMPONENT_SERVICE_NAME_PROPERTY_ID, "HDFS");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+    try {
+      provider.createResources(request);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (SystemException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testUpdateResources() throws Exception {
+    Resource.Type type = Resource.Type.ClientConfig;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+    RequestStatusResponse response = createNiceMock(RequestStatusResponse.class);
+
+    // replay
+    replay(managementController, response);
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    // add the property map to a set for the request.
+    Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+    // create the request
+    Request request = PropertyHelper.getUpdateRequest(properties, null);
+
+    Predicate predicate = new PredicateBuilder().property(ClientConfigResourceProvider.COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals("c1").
+        toPredicate();
+
+    try {
+      provider.updateResources(request, predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (SystemException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController, response);
+  }
+
+  @Test
+  public void testDeleteResources() throws Exception {
+    Resource.Type type = Resource.Type.ClientConfig;
+
+    AmbariManagementController managementController = createMock(AmbariManagementController.class);
+
+    // replay
+    replay(managementController);
+
+    ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(
+        type,
+        PropertyHelper.getPropertyIds(type),
+        PropertyHelper.getKeyPropertyIds(type),
+        managementController);
+
+    Predicate predicate = new PredicateBuilder().property(ClientConfigResourceProvider.COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals("HDFS_CLIENT").
+        toPredicate();
+    try {
+      provider.deleteResources(predicate);
+      Assert.fail("Expected an UnsupportedOperationException");
+    } catch (SystemException e) {
+      // expected
+    }
+
+    // verify
+    verify(managementController);
+  }
+
+}

+ 2 - 1
ambari-server/src/test/python/stacks/1.3.2/HDFS/test_datanode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestDatanode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/1.3.2/HDFS/test_namenode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestNamenode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/1.3.2/HDFS/test_snamenode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestSNamenode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/2.0.6/HDFS/test_datanode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestDatanode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/2.0.6/HDFS/test_journalnode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestJournalnode(RMFTestCase):
 
   def test_configure_default(self):

+ 3 - 0
ambari-server/src/test/python/stacks/2.0.6/HDFS/test_namenode.py

@@ -16,11 +16,14 @@ 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.
+from ambari_commons import OSCheck
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
 
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestNamenode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/2.0.6/HDFS/test_snamenode.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestSNamenode(RMFTestCase):
 
   def test_configure_default(self):

+ 2 - 1
ambari-server/src/test/python/stacks/2.0.6/HDFS/test_zkfc.py

@@ -17,10 +17,11 @@ 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.
 '''
+from ambari_commons import OSCheck
 from mock.mock import MagicMock, patch
 from stacks.utils.RMFTestCase import *
 
-
+@patch.object(OSCheck,"get_os_type", new = MagicMock(return_value='suse'))
 class TestZkfc(RMFTestCase):
 
   def test_start_default(self):

+ 3 - 2
ambari-server/src/test/python/stacks/2.0.6/configs/default.json

@@ -27,8 +27,9 @@
         "script": "scripts/service_check.py",
         "excluded_hosts": "host1,host2",
         "mark_draining_only" : "false",
-        "xml_configs_list":"[{\"hdfs-site.xml\":\"hdfs-site\"}]",
-        "env_configs_list":"[{\"hadoop-env.sh\":\"hadoop-env\"}]"
+        "xml_configs_list":[{"hdfs-site.xml":"hdfs-site"}],
+        "env_configs_list":[{"hadoop-env.sh":"hadoop-env"}],
+        "output_file":"HDFS_CLIENT-configs.tar.gz"
 
     },
     "taskId": 152, 

+ 12 - 0
ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HIVE/metainfo.xml

@@ -98,6 +98,18 @@
             <script>scripts/hive_client.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hive-site.xml</fileName>
+              <dictionaryName>hive-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hive-env.sh</fileName>
+              <dictionaryName>hive-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>
 

+ 3 - 0
ambari-server/src/test/resources/stacks/HDP/2.0.5/services/YARN/metainfo.xml

@@ -76,6 +76,9 @@
             <scriptType>PYTHON</scriptType>
             <timeout>600</timeout>
           </commandScript>
+          <downloads>
+            <source>/etc/hadoop/conf</source>
+          </downloads>
         </component>
       </components>
 

+ 13 - 1
ambari-server/src/test/resources/stacks/HDP/2.0.7/services/HIVE/metainfo.xml

@@ -97,9 +97,21 @@
           <category>CLIENT</category>
           <cardinality>0+</cardinality>
           <commandScript>
-            <script>scripts/hive_client.py</script>
+            <script>scripts/hive_client222.py</script>
             <scriptType>PYTHON</scriptType>
           </commandScript>
+          <configFiles>
+            <configFile>
+              <type>xml</type>
+              <fileName>hive-site.xml</fileName>
+              <dictionaryName>hive-site</dictionaryName>
+            </configFile>
+            <configFile>
+              <type>env</type>
+              <fileName>hive-env.sh</fileName>
+              <dictionaryName>hive-env</dictionaryName>
+            </configFile>
+          </configFiles>
         </component>
       </components>