Procházet zdrojové kódy

Merge branch 'trunk' into branch-alerts-dev

Conflicts:
	ambari-server/conf/unix/ambari.properties
	ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
Jonathan Hurley před 10 roky
rodič
revize
aaf051357d
100 změnil soubory, kde provedl 2902 přidání a 623 odebrání
  1. 5 2
      ambari-admin/src/main/resources/ui/admin-web/app/index.html
  2. 2 1
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/app.js
  3. 1 6
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js
  4. 4 4
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js
  5. 1 1
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js
  6. 12 6
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js
  7. 29 0
      ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js
  8. 9 0
      ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css
  9. 5 5
      ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html
  10. 1 1
      ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html
  11. 2 2
      ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html
  12. 7 8
      ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html
  13. 4 4
      ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html
  14. 3 1
      ambari-admin/src/main/resources/ui/admin-web/bower.json
  15. 8 1
      ambari-common/src/main/python/resource_management/libraries/providers/execute_hadoop.py
  16. 12 4
      ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py
  17. 1 0
      ambari-common/src/main/python/resource_management/libraries/resources/execute_hadoop.py
  18. 1 0
      ambari-common/src/main/python/resource_management/libraries/resources/hdfs_directory.py
  19. 1 1
      ambari-server/conf/unix/ambari.properties
  20. 188 96
      ambari-server/docs/api/v1/clusters-cluster.md
  21. 2 3
      ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
  22. 12 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
  23. 1 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java
  24. 3 3
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java
  25. 2 0
      ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
  26. 120 0
      ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java
  27. 223 0
      ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java
  28. 132 297
      ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
  29. 85 15
      ambari-server/src/main/python/ambari-server.py
  30. 40 0
      ambari-server/src/main/resources/ganglia_properties.json
  31. 15 5
      ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/params.py
  32. 2 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-INSTALL/scripts/params.py
  33. 3 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/files/checkForFormat.sh
  34. 19 6
      ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
  35. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/flume.py
  36. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/flume_check.py
  37. 12 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/params.py
  38. 2 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/files/hbaseSmokeVerify.sh
  39. 29 8
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/params.py
  40. 3 3
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/service_check.py
  41. 3 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/files/checkForFormat.sh
  42. 9 6
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/hdfs_namenode.py
  43. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/namenode.py
  44. 24 10
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/params.py
  45. 20 7
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/service_check.py
  46. 6 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hcat.py
  47. 6 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hcat_service_check.py
  48. 2 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive.py
  49. 6 3
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py
  50. 4 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/install_jars.py
  51. 49 24
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/params.py
  52. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/templates/startHiveserver2.sh.j2
  53. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/configuration/oozie-env.xml
  54. 4 4
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/files/oozieSmoke2.sh
  55. 2 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/scripts/oozie_service.py
  56. 18 6
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/scripts/params.py
  57. 17 3
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/package/scripts/params.py
  58. 6 4
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/package/scripts/service_check.py
  59. 9 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/SQOOP/package/scripts/params.py
  60. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/configuration/webhcat-env.xml
  61. 30 11
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/package/scripts/params.py
  62. 7 4
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/package/scripts/webhcat.py
  63. 31 14
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py
  64. 3 2
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/resourcemanager.py
  65. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py
  66. 2 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service_check.py
  67. 7 7
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/yarn.py
  68. 13 4
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/ZOOKEEPER/package/scripts/params.py
  69. 13 2
      ambari-server/src/main/resources/stacks/HDP/2.1/services/FALCON/package/scripts/params.py
  70. 2 3
      ambari-server/src/main/resources/stacks/HDP/2.1/services/STORM/package/scripts/params.py
  71. 23 0
      ambari-server/src/main/resources/stacks/HDP/2.2/metainfo.xml
  72. 82 0
      ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml
  73. 88 0
      ambari-server/src/main/resources/stacks/HDP/2.2/role_command_order.json
  74. 28 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/FALCON/metainfo.xml
  75. 40 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/FLUME/metainfo.xml
  76. 42 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/HBASE/metainfo.xml
  77. 29 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/hadoop-env.xml
  78. 34 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/hdfs-site.xml
  79. 68 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/metainfo.xml
  80. 44 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/HIVE/metainfo.xml
  81. 45 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/configuration/oozie-site.xml
  82. 28 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/metainfo.xml
  83. 41 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/PIG/metainfo.xml
  84. 29 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/SQOOP/metainfo.xml
  85. 29 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/storm-env.xml
  86. 54 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/storm-site.xml
  87. 29 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/metainfo.xml
  88. 40 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/TEZ/metainfo.xml
  89. 59 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/WEBHCAT/configuration/webhcat-site.xml
  90. 44 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/WEBHCAT/metainfo.xml
  91. 36 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml
  92. 35 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml
  93. 71 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/metainfo.xml
  94. 40 0
      ambari-server/src/main/resources/stacks/HDP/2.2/services/ZOOKEEPER/metainfo.xml
  95. 1 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java
  96. 413 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessorTest.java
  97. 76 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
  98. 1 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java
  99. 50 0
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderBaseTest.java
  100. 2 2
      ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDNWithSpaceTest.java

+ 5 - 2
ambari-admin/src/main/resources/ui/admin-web/app/index.html

@@ -29,6 +29,7 @@
     <!-- bower:css -->
     <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
     <link rel="stylesheet" href="bower_components/angular-bootstrap-toggle-switch/style/bootstrap3/angular-toggle-switch-bootstrap-3.css" />
+    <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css"/>
     <!-- endbower -->
     <!-- endbuild -->
 
@@ -52,12 +53,12 @@
               <li>
                 <div class="btn-group" dropdown is-open="status.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle navbar-btn" ng-disabled="disabled">
-                    {{currentUser}} <span class="caret"></span>
+                    <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span>
                   </button>
                   <ul class="dropdown-menu" role="menu">
                     <li><a href ng-click="about()">About</a></li>
                     <li class="divider"></li>
-                    <li><a href ng-click="signOut()">Sign Out</a></li>
+                    <li><a href ng-click="signOut()">Sign out</a></li>
                   </ul>
                 </div>
               </li>
@@ -91,6 +92,7 @@
     <script src="bower_components/lodash/dist/lodash.compat.js"></script>
     <script src="bower_components/restangular/dist/restangular.js"></script>
     <script src="bower_components/angular-bootstrap-toggle-switch/angular-toggle-switch.min.js"></script>
+    <script src="bower_components/angular-translate/angular-translate.min.js"></script>
     <!-- endbower -->
     <!-- endbuild -->
 
@@ -112,6 +114,7 @@
     <!-- build:js scripts/main.js -->
     <script src="scripts/app.js"></script>
     <script src="scripts/routes.js"></script>
+    <script src="scripts/i18n.config.js"></script>
     <script src="scripts/controllers/mainCtrl.js"></script>
     <script src="scripts/controllers/NavbarCtrl.js"></script>
     <script src="scripts/controllers/users/UsersCreateCtrl.js"></script>

+ 2 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/app.js

@@ -23,7 +23,8 @@ angular.module('ambariAdminConsole', [
   'ui.bootstrap',
   'restangular',
   'angularAlert',
-  'toggle-switch'
+  'toggle-switch',
+  'pascalprecht.translate'
 ])
 .constant('Settings',{
 	baseUrl: '/api/v1'

+ 1 - 6
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js

@@ -49,11 +49,7 @@ angular.module('ambariAdminConsole')
 
   // Get META for properties
   View.getMeta($routeParams.viewId, $routeParams.version).then(function(data) {
-    var meta = {};
-    angular.forEach(data.data.ViewVersionInfo.parameters, function(parameter) {
-      meta[parameter.name] = parameter;
-    });
-    $scope.configurationMeta = meta;
+    $scope.configurationMeta = data.data.ViewVersionInfo.parameters;
     reloadViewInfo();
   });
 
@@ -76,7 +72,6 @@ angular.module('ambariAdminConsole')
 
   $scope.permissions = [];
   
-  // reloadViewInfo();
   reloadViewPrivilegies();
 
   $scope.editSettingsDisabled = true;

+ 4 - 4
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/groups/GroupsEditCtrl.js

@@ -86,13 +86,13 @@ angular.module('ambariAdminConsole')
       privilegie = privilegie.PrivilegeInfo;
       if(privilegie.type === 'CLUSTER'){
         // This is cluster
-        privilegies.clusters[privilegie.cluster_name] = privilegies.clusters[privilegie.cluster_name] || '';
-        privilegies.clusters[privilegie.cluster_name] += privilegies.clusters[privilegie.cluster_name] ? ', ' + privilegie.permission_name : privilegie.permission_name;
+        privilegies.clusters[privilegie.cluster_name] = privilegies.clusters[privilegie.cluster_name] || [];
+        privilegies.clusters[privilegie.cluster_name].push(privilegie.permission_name);
       } else if ( privilegie.type === 'VIEW'){
-        privilegies.views[privilegie.instance_name] = privilegies.views[privilegie.instance_name] || { privileges:''};
+        privilegies.views[privilegie.instance_name] = privilegies.views[privilegie.instance_name] || { privileges:[]};
         privilegies.views[privilegie.instance_name].version = privilegie.version;
         privilegies.views[privilegie.instance_name].view_name = privilegie.view_name;
-        privilegies.views[privilegie.instance_name].privileges += privilegies.views[privilegie.instance_name].privileges ? ', ' + privilegie.permission_name : privilegie.permission_name;
+        privilegies.views[privilegie.instance_name].privileges.push(privilegie.permission_name);
       }
     });
 

+ 1 - 1
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/mainCtrl.js

@@ -39,4 +39,4 @@ angular.module('ambariAdminConsole')
   };
 
   $scope.currentUser = Auth.getCurrentUser();
-}]);
+}]);

+ 12 - 6
ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/users/UsersShowCtrl.js

@@ -122,7 +122,7 @@ angular.module('ambariAdminConsole')
 
   $scope.toggleUserActive = function() {
     if(!$scope.isCurrentUser){
-      ConfirmationModal.show('Change Status', 'Are you sure you want to change "'+ $scope.user.user_name +'" status?').then(function() {
+      ConfirmationModal.show('Change Status', 'Are you sure you want to change status for user "'+ $scope.user.user_name +'" to '+($scope.user.active ? 'inactive' : 'active')+'?').then(function() {
         User.setActive($scope.user.user_name, $scope.user.active);
       })
       .catch(function() {
@@ -132,7 +132,13 @@ angular.module('ambariAdminConsole')
   };    
   $scope.toggleUserAdmin = function() {
     if(!$scope.isCurrentUser){
-      ConfirmationModal.show('Change Admin Privilege', 'Are you sure you want to change "'+$scope.user.user_name+'" Admin privilege?').then(function() {
+      var message = '';
+      if( !$scope.user.admin ){
+        message = 'Are you sure you want to grant Admin privilege to user ';
+      } else {
+        message = 'Are you sure you want to revoke Admin privilege from user ';
+      }
+      ConfirmationModal.show('Change Admin Privilege', message + '"'+$scope.user.user_name+'"?').then(function() {
         User.setAdmin($scope.user.user_name, $scope.user.admin)
         .then(function() {
           loadPrivilegies();
@@ -164,13 +170,13 @@ angular.module('ambariAdminConsole')
         privilegie = privilegie.PrivilegeInfo;
         if(privilegie.type === 'CLUSTER'){
           // This is cluster
-          privilegies.clusters[privilegie.cluster_name] = privilegies.clusters[privilegie.cluster_name] || '';
-          privilegies.clusters[privilegie.cluster_name] += privilegies.clusters[privilegie.cluster_name] ? ', ' + privilegie.permission_name : privilegie.permission_name;
+          privilegies.clusters[privilegie.cluster_name] = privilegies.clusters[privilegie.cluster_name] || [];
+          privilegies.clusters[privilegie.cluster_name].push(privilegie.permission_name);
         } else if ( privilegie.type === 'VIEW'){
-          privilegies.views[privilegie.instance_name] = privilegies.views[privilegie.instance_name] || { privileges:''};
+          privilegies.views[privilegie.instance_name] = privilegies.views[privilegie.instance_name] || { privileges:[]};
           privilegies.views[privilegie.instance_name].version = privilegie.version;
           privilegies.views[privilegie.instance_name].view_name = privilegie.view_name;
-          privilegies.views[privilegie.instance_name].privileges += privilegies.views[privilegie.instance_name].privileges ? ', ' + privilegie.permission_name : privilegie.permission_name;
+          privilegies.views[privilegie.instance_name].privileges.push(privilegie.permission_name);
 
         }
       });

+ 29 - 0
ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js

@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+'use strict';
+
+angular.module('ambariAdminConsole')
+.config(['$translateProvider', function($translateProvider) {
+  $translateProvider.translations('en',{
+    'CLUSTER.OPERATE': 'Operator',
+    'CLUSTER.READ': 'Read-Only',
+    'VIEW.USE': 'Use'
+  });
+
+  $translateProvider.preferredLanguage('en');
+}]);

+ 9 - 0
ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css

@@ -191,6 +191,9 @@
   ------ END editable-list DIRECTIVE SECTION ------ -
 */
 
+.tooltip-inner{
+  word-wrap: break-word;
+}
 
  .instances-table{
   table-layout: fixed;
@@ -962,3 +965,9 @@ button.btn.btn-xs{
   float: left;
   margin-right: 5px;
 }
+
+.no-animation *{
+  -webkit-transition: none!important;
+  -o-transition: none!important;
+  transition: none!important;
+}

+ 5 - 5
ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html

@@ -108,7 +108,7 @@
       <tbody>
         <tr ng-repeat="permission in permissions">
           <td>
-            <label class="">{{permission.PermissionInfo.permission_name}}</label>
+            <label class="" tooltip="{{permission.PermissionInfo.permission_name}}">{{permission.PermissionInfo.permission_name | translate}}</label>
           </td>
           <td>
             <editable-list items-source="permissionsEdit[permission.PermissionInfo.permission_name].USER" editable="true" resource-type="User"></editable-list>
@@ -136,11 +136,11 @@
   <div class="panel-body">
     <form name="propertiesForm" class="form-horizontal" ng-hide="isConfigurationEmpty" novalidate>
       <fieldset ng-disabled="editConfigurationDisabled">
-        <div class="form-group" ng-repeat="(propertyName, propertyValue) in configurationMeta" ng-class="{'has-error' : propertyValue.required && propertiesForm[propertyName].$error.required && !editConfigurationDisabled}">
-          <label for="" class="control-label col-sm-3" ng-class="{'not-required': !propertyValue.required}" tooltip="{{propertyValue.description}}">{{propertyName}}{{propertyValue.required ? '*' : ''}}</label>
+        <div class="form-group" ng-repeat="property in configurationMeta" ng-class="{'has-error' : property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled}">
+          <label for="" class="control-label col-sm-3" ng-class="{'not-required': !property.required}" tooltip="{{property.description}}">{{property.name}}{{property.required ? '*' : ''}}</label>
           <div class="col-sm-9">
-            <input type="{{propertyValue.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="propertyValue.required" name="{{propertyName}}" ng-model="configuration[propertyName]">
-            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='propertyValue.required && propertiesForm[propertyName].$error.required && !editConfigurationDisabled'>
+            <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required" name="{{property.name}}" ng-model="configuration[property.name]">
+            <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled'>
               This field is required.
             </div>
           </div>

+ 1 - 1
ambari-admin/src/main/resources/ui/admin-web/app/views/clusters/manageAccess.html

@@ -33,7 +33,7 @@
     </thead>
     <tbody>
       <tr ng-repeat="permission in permissions">
-        <td><label class="">{{permission.PermissionInfo.permission_name}}</label></td>
+        <td><label class="" tooltip="{{permission.PermissionInfo.permission_name}}">{{permission.PermissionInfo.permission_name | translate}}</label></td>
         <td>
           <div class="" ng-switch="isEditMode">
             <editable-list items-source="permissionsEdit[permission.PermissionInfo.permission_name].USER" resource-type="User" editable="true"></editable-list>

+ 2 - 2
ambari-admin/src/main/resources/ui/admin-web/app/views/groups/edit.html

@@ -61,7 +61,7 @@
                 <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
               </td>
               <td>
-                {{privilege}}
+                <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
             <tr ng-repeat="(name, privilege) in privileges.views">
@@ -70,7 +70,7 @@
                 <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
               </td>
               <td>
-                {{privilege.privileges}}
+                <span tooltip="{{item}}" ng-repeat="item in privilege.privileges">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
           </tbody>

+ 7 - 8
ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html

@@ -38,17 +38,16 @@
                   class="form-control input-sm"
                   tooltip="Only alpha-numeric characters."
                   tooltip-trigger="focus">
-
-              <button
-                  type="submit"
-                  class="btn btn-success btn-xs"
-                  ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}">
-                <i class="glyphicon glyphicon-ok"></i>
-              </button>
               <button ng-click="toggleEditName()"
-                      class="btn btn-danger btn-xs">
+                      class="btn btn-xs">
                 <i class="glyphicon glyphicon-remove"></i>
               </button>
+              <button
+                    type="submit"
+                    class="btn btn-primary btn-xs"
+                    ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}">
+                <i class="glyphicon glyphicon-ok"></i>
+              </button>
             </div>
           </form>
 

+ 4 - 4
ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html

@@ -40,13 +40,13 @@
     <div class="form-group">
       <label for="" class="col-sm-2 control-label">Status</label>
       <div class="col-sm-10">
-        <toggle-switch on-change="toggleUserActive()" disabled-tooltip="Cannot Change Status" ng-disabled="isCurrentUser" model="user.active" on-label="Active" off-label="Inactive" class="switch-primary userstatus" data-off-color="danger"></toggle-switch>
+        <toggle-switch on-change="toggleUserActive()" disabled-tooltip="Cannot Change Status" ng-disabled="isCurrentUser" model="user.active" on-label="Active" off-label="Inactive" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
       </div>
     </div>
     <div class="form-group">
       <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span> Ambari Admin</label>
       <div class="col-sm-10">
-        <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="Cannot Change Admin" ng-disabled="isCurrentUser" model="user.admin" on-label="Yes" off-label="No" class="switch-primary userstatus" data-off-color="danger"></toggle-switch>
+        <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="Cannot Change Admin" ng-disabled="isCurrentUser" model="user.admin" on-label="Yes" off-label="No" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch>
       </div>
     </div>
     <div class="form-group">
@@ -83,7 +83,7 @@
                 <a href="#/clusters/{{name}}/manageAccess">{{name}}</a>
               </td>
               <td>
-                {{privilege}}
+                <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | translate}}{{$last ? '' : ', '}}</span>
               </td>
             </tr>
             <tr ng-repeat="(name, privilege) in privileges.views">
@@ -92,7 +92,7 @@
                 <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a>
               </td>
               <td>
-                {{privilege.privileges}}
+                <span tooltip="{{item}}" ng-repeat="item in privilege.privileges">{{item | translate}}{{$last ? '' : ', '}}</span> 
               </td>
             </tr>
           </tbody>

+ 3 - 1
ambari-admin/src/main/resources/ui/admin-web/bower.json

@@ -8,7 +8,9 @@
     "angular-bootstrap": "~0.11.0",
     "restangular": "~1.4.0",
     "angular-bootstrap-toggle-switch": "~0.5.1",
-    "angular-animate": "~1.2.23"
+    "angular-animate": "~1.2.23",
+    "angular-translate": "~2.2.0",
+    "font-awesome": "~4.2.0"
   },
   "devDependencies": {}
 }

+ 8 - 1
ambari-common/src/main/python/resource_management/libraries/providers/execute_hadoop.py

@@ -19,6 +19,7 @@ limitations under the License.
 Ambari Agent
 
 """
+import os
 
 from resource_management import *
 
@@ -27,6 +28,7 @@ class ExecuteHadoopProvider(Provider):
     kinit__path_local = self.resource.kinit_path_local
     keytab = self.resource.keytab
     conf_dir = self.resource.conf_dir
+    bin_dir = self.resource.bin_dir
     command = self.resource.command
     principal = self.resource.principal
     
@@ -39,10 +41,15 @@ class ExecuteHadoopProvider(Provider):
           path = ['/bin'],
           user = self.resource.user
         )
-    
+
+      path = os.environ['PATH']
+      if bin_dir is not None:
+        path += os.pathsep + bin_dir
+
       Execute (format("hadoop --config {conf_dir} {command}"),
         user        = self.resource.user,
         tries       = self.resource.tries,
         try_sleep   = self.resource.try_sleep,
         logoutput   = self.resource.logoutput,
+        environment = {'PATH' : path}
       )

+ 12 - 4
ambari-common/src/main/python/resource_management/libraries/providers/hdfs_directory.py

@@ -19,6 +19,7 @@ limitations under the License.
 Ambari Agent
 
 """
+import os
 
 from resource_management import *
 directories_list = [] #direcotries list for mkdir
@@ -68,6 +69,7 @@ class HdfsDirectoryProvider(Provider):
     secured = self.resource.security_enabled
     keytab_file = self.resource.keytab
     kinit_path = self.resource.kinit_path_local
+    bin_dir = self.resource.bin_dir
 
     chmod_commands = []
     chown_commands = []
@@ -76,7 +78,7 @@ class HdfsDirectoryProvider(Provider):
       mode = chmod_key[0]
       recursive = chmod_key[1]
       chmod_dirs_str = ' '.join(chmod_dirs)
-      chmod_commands.append(format("hadoop fs -chmod {recursive} {mode} {chmod_dirs_str}"))
+      chmod_commands.append(format("hadoop --config {hdp_conf_dir} fs -chmod {recursive} {mode} {chmod_dirs_str}"))
 
     for chown_key, chown_dirs in chown_map.items():
       owner = chown_key[0]
@@ -87,7 +89,7 @@ class HdfsDirectoryProvider(Provider):
         chown = owner
         if group:
           chown = format("{owner}:{group}")
-        chown_commands.append(format("hadoop fs -chown {recursive} {chown} {chown_dirs_str}"))
+        chown_commands.append(format("hadoop --config {hdp_conf_dir} fs -chown {recursive} {chown} {chown_dirs_str}"))
 
     if secured:
         Execute(format("{kinit_path} -kt {keytab_file} {hdfs_principal_name}"),
@@ -97,11 +99,17 @@ class HdfsDirectoryProvider(Provider):
     #for hadoop 2 we need to specify -p to create directories recursively
     parent_flag = '`rpm -q hadoop | grep -q "hadoop-1" || echo "-p"`'
 
-    Execute(format('hadoop fs -mkdir {parent_flag} {dir_list_str} && {chmod_cmd} && {chown_cmd}',
+    path = os.environ['PATH']
+    if bin_dir is not None:
+      path += os.pathsep + bin_dir
+
+    Execute(format('hadoop --config {hdp_conf_dir} fs -mkdir {parent_flag} {dir_list_str} && {chmod_cmd} && {chown_cmd}',
                    chmod_cmd=' && '.join(chmod_commands),
                    chown_cmd=' && '.join(chown_commands)),
             user=hdp_hdfs_user,
-            not_if=format("su - {hdp_hdfs_user} -c 'hadoop fs -ls {dir_list_str}'")
+            environment = {'PATH' : path},
+            not_if=format("su - {hdp_hdfs_user} -c 'export PATH=$PATH:{bin_dir} ; "
+                          "hadoop --config {hdp_conf_dir} fs -ls {dir_list_str}'")
     )
 
     directories_list[:] = []

+ 1 - 0
ambari-common/src/main/python/resource_management/libraries/resources/execute_hadoop.py

@@ -32,6 +32,7 @@ class ExecuteHadoop(Resource):
   user = ResourceArgument()
   logoutput = BooleanArgument(default=False)
   principal = ResourceArgument(default=lambda obj: obj.user)
+  bin_dir = ResourceArgument() # appended to $PATH
   
   conf_dir = ResourceArgument()
   

+ 1 - 0
ambari-common/src/main/python/resource_management/libraries/resources/hdfs_directory.py

@@ -38,6 +38,7 @@ class HdfsDirectory(Resource):
   keytab = ResourceArgument()
   kinit_path_local = ResourceArgument()
   hdfs_user = ResourceArgument()
+  bin_dir = ResourceArgument(default="")
 
   #action 'create' immediately creates all pending directory in efficient manner
   #action 'create_delayed' add directory to list of pending directories

+ 1 - 1
ambari-server/conf/unix/ambari.properties

@@ -55,4 +55,4 @@ agent.threadpool.size.max=25
 ulimit.open.files=10000
 
 # Server HTTP settings
-server.http.session.inactive_timeout=60
+server.http.session.inactive_timeout=1800

+ 188 - 96
ambari-server/docs/api/v1/clusters-cluster.md

@@ -60,105 +60,197 @@ Returns information for the specified cluster identified by ":name"
 
 **Example**
 
-Get information for the cluster "c1".
+Get information for the cluster "cluster001".
 
-    GET /clusters/c1
+    GET /clusters/cluster001
     
     200 OK
     {
-    	"href" : "http://your.ambari.server/api/v1/clusters/c1",
-      	"Clusters" : {
-        	"cluster_name" : "c1",
-        	"cluster_id" : 1,
-        	"version" : "HDP-1.2.0"
-      	},
-      	"services" : [
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/NAGIOS",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "NAGIOS"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/HCATALOG",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "HCATALOG"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/PIG",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-         			"service_name" : "PIG"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/MAPREDUCE",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "MAPREDUCE"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/GANGLIA",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "GANGLIA"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/HIVE",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "HIVE"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/HDFS",
-        		"ServiceInfo" : {
-          			"cluster_name" : "MyIE9",
-          			"service_name" : "HDFS"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/ZOOKEEPER",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-         	 		"service_name" : "ZOOKEEPER"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/HBASE",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "HBASE"
-          		}
-        	},
-        	{
-        		"href" : "http://your.ambari.server/api/v1/clusters/c1/services/OOZIE",
-        		"ServiceInfo" : {
-          			"cluster_name" : "c1",
-          			"service_name" : "OOZIE"
-          		}
-        	} 
+    	"href" : "http://your.ambari.server/api/v1/clusters/cluster001",
+    	"Clusters" : {
+    		"cluster_id" : 9,
+    		"cluster_name" : "cluster001",
+    		"health_report" : {
+    			"Host/stale_config" : 1,
+    			"Host/maintenance_state" : 0,
+    			"Host/host_state/HEALTHY" : 3,
+    			"Host/host_state/UNHEALTHY" : 0,
+    			"Host/host_state/HEARTBEAT_LOST" : 0,
+    			"Host/host_state/INIT" : 0,
+    			"Host/host_status/HEALTHY" : 3,
+    			"Host/host_status/UNHEALTHY" : 0,
+    			"Host/host_status/UNKNOWN" : 0,
+    			"Host/host_status/ALERT" : 0
+    		},
+    		"provisioning_state" : "INIT",
+    		"total_hosts" : 3,
+    		"version" : "HDP-2.0",
+    		"desired_configs" : {
+    			"capacity-scheduler" : {
+    				"user" : "admin",
+    				"tag" : "version1408514705943"
+    			},
+    			"core-site" : {
+    				"user" : "admin",
+    				"tag" : "version1409806913314"
+    			},
+    			"global" : {
+    				"user" : "admin",
+    				"tag" : "version1409806913314"
+    			},
+    			"hdfs-log4j" : {
+    				"user" : "admin",
+    				"tag" : "version1"
+    			},
+    			"hdfs-site" : {
+    				"user" : "admin",
+    				"tag" : "version1407908591996"
+    			},
+    			"mapred-site" : {
+    				"user" : "admin",
+    				"tag" : "version1408514705943"
+    			},
+    			"mapreduce2-log4j" : {
+    				"user" : "admin",
+    				"tag" : "version1408514705943"
+    			},
+    			"yarn-log4j" : {
+    				"user" : "admin",
+    				"tag" : "version1408514705943"
+    			},
+    			"yarn-site" : {
+    				"user" : "admin",
+    				"tag" : "version1408514705943"
+    			},
+    			"zoo.cfg" : {
+    				"user" : "admin",
+    				"tag" : "version1"
+    			},
+    			"zookeeper-log4j" : {
+    				"user" : "admin",
+    				"tag" : "version1"
+    			}
+    		}
+    	},
+    	"alerts" : {
+    		"summary" : {
+    			"CRITICAL" : 1,
+    			"OK" : 2,
+    			"PASSIVE" : 0,
+    			"WARNING" : 0
+    		}
+    	},
+    	"requests" : [
+    		{
+    			"href" : "http://your.ambari.server/api/v1/clusters/cluster001/requests/304",
+    			"Requests" : {
+    			"cluster_name" : "cluster001",
+    			"id" : 304
+    			}
+    		},
+    		{
+    			"href" : "http://your.ambari.server/api/v1/clusters/cluster001/requests/305",
+    			"Requests" : {
+    			"cluster_name" : "cluster001",
+    			"id" : 305
+    			}
+    		}
+    		],
+    	"services" : [
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/services/GANGLIA",
+    		"ServiceInfo" : {
+    		"cluster_name" : "cluster001",
+    		"service_name" : "GANGLIA"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/services/HDFS",
+    		"ServiceInfo" : {
+    		"cluster_name" : "cluster001",
+    		"service_name" : "HDFS"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/services/MAPREDUCE2",
+    		"ServiceInfo" : {
+    		"cluster_name" : "cluster001",
+    		"service_name" : "MAPREDUCE2"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/services/ZOOKEEPER",
+    		"ServiceInfo" : {
+    		"cluster_name" : "cluster001",
+    		"service_name" : "ZOOKEEPER"
+    		}
+    	}
     	],
-      "hosts" : [
-        {
-          "href" : "http://your.ambari.server/api/v1/clusters/c1/hosts/some.host",
-          "Hosts" : {
-              "cluster_name" : "c1",
-              "host_name" : "some.host"
-          }
-        },
-        {
-          "href" : "http://your.ambari.server/api/v1/clusters/c1/hosts/another.host",
-          "Hosts" : {
-              "cluster_name" : "c1",
-              "host_name" : "another.host"
-          }
-        }
-      ]
+    	"config_groups" : [
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/config_groups/2",
+    		"ConfigGroup" : {
+    		 "cluster_name" : "cluster001",
+    		  "id" : 2
+    		}
+    	}
+    	],
+    	"workflows" : [ ],
+    	"hosts" : [
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/hosts/host1.domain.com",
+    		"Hosts" : {
+    		  "cluster_name" : "cluster001",
+    		  "host_name" : "host1.domain.com"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/hosts/host2.domain.com",
+    		"Hosts" : {
+    		  "cluster_name" : "cluster001",
+    		  "host_name" : "host2.domain.com"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/hosts/host3.domain.com",
+    		"Hosts" : {
+    		  "cluster_name" : "cluster001",
+    		  "host_name" : "host3.domain.com"
+    		}
+    	}
+    	],
+    	"configurations" : [
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/configurations?type=core-site&tag=version1",
+    		"tag" : "version1",
+    		"type" : "core-site",
+    		"Config" : {
+    		  "cluster_name" : "cluster001"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/configurations?type=global&tag=version1",
+    		"tag" : "version1",
+    		"type" : "global",
+    		"Config" : {
+    		  "cluster_name" : "cluster001"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/configurations?type=hdfs-site&tag=version1",
+    		"tag" : "version1",
+    		"type" : "hdfs-site",
+    		"Config" : {
+    		  "cluster_name" : "cluster001"
+    		}
+    	},
+    	{
+    		"href" : "http://your.ambari.server/api/v1/clusters/cluster001/configurations?type=zoo.cfg&tag=version1",
+    		"tag" : "version1",
+    		"type" : "zoo.cfg",
+    		"Config" : {
+    		  "cluster_name" : "cluster001"
+    		}
+    	},
+    	]
     }
-

+ 2 - 3
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -106,7 +106,6 @@ public class Configuration {
   public static final String CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY = "client.api.ssl.cert_pass_file";
   public static final String CLIENT_API_SSL_CRT_PASS_KEY = "client.api.ssl.crt_pass";
   public static final String CLIENT_API_SSL_KEY_NAME_KEY = "client.api.ssl.key_name";
-  public static final String SERVER_DB_TYPE_KEY = "server.jdbc.database";       // E.g., oracle|mysql|postgres
   public static final String SERVER_DB_NAME_KEY = "server.jdbc.database_name";
   public static final String SERVER_DB_NAME_DEFAULT = "ambari";
   public static final String SERVER_JDBC_POSTGRES_SCHEMA_NAME = "server.jdbc.postgres.schema";
@@ -1098,11 +1097,11 @@ public class Configuration {
    * REST APIs will create new sessions that are never reaped since their
    * default time is -1.
    *
-   * @return the time value or {@code 60} seconds for default.
+   * @return the time value or {@code 1800} seconds for default.
    */
   public int getHttpSessionInactiveTimeout() {
     return Integer.parseInt(properties.getProperty(
         SERVER_HTTP_SESSION_INACTIVE_TIMEOUT,
-        "60"));
+        "1800"));
   }
 }

+ 12 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java

@@ -595,6 +595,11 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
       return version;
     }
 
+
+    Map<DependencyInfo, String> getDependencyConditionalServiceMap() {
+      return dependencyConditionalServiceMap;
+    }
+
     /**
      * Get services contained in the stack.
      *
@@ -842,13 +847,19 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
      * Register conditional dependencies.
      */
     //todo: This information should be specified in the stack definition.
-    private void registerConditionalDependencies() {
+    void registerConditionalDependencies() {
       Collection<DependencyInfo> nagiosDependencies = getDependenciesForComponent("NAGIOS_SERVER");
       for (DependencyInfo dependency : nagiosDependencies) {
         if (dependency.getComponentName().equals("HCAT")) {
           dependencyConditionalServiceMap.put(dependency, "HCATALOG");
         } else if (dependency.getComponentName().equals("OOZIE_CLIENT")) {
           dependencyConditionalServiceMap.put(dependency, "OOZIE");
+        } else if (dependency.getComponentName().equals("YARN_CLIENT")) {
+          dependencyConditionalServiceMap.put(dependency, "YARN");
+        } else if (dependency.getComponentName().equals("TEZ_CLIENT")) {
+          dependencyConditionalServiceMap.put(dependency, "TEZ");
+        } else if (dependency.getComponentName().equals("MAPREDUCE2_CLIENT")) {
+          dependencyConditionalServiceMap.put(dependency, "MAPREDUCE2");
         }
       }
       dbDependencyInfo.put("MYSQL_SERVER", "global/hive_database");

+ 1 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceConfigVersionResourceProvider.java

@@ -170,7 +170,7 @@ public class ServiceConfigVersionResourceProvider extends
       configMap.put("type", config.getType());
       configMap.put("tag", config.getVersionTag());
       configMap.put("version", config.getVersion());
-      configMap.put("properties", config.getConfigs());
+      configMap.put("properties", new TreeMap(config.getConfigs()));
       configMap.put("properties_attributes", config.getConfigAttributes());
       result.add(configMap);
     }

+ 3 - 3
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProvider.java

@@ -176,9 +176,9 @@ public abstract class StackAdvisorResourceProvider extends ReadOnlyResourceProvi
     return map;
   }
 
-  private static final String CONFIGURATIONS_PROPERTY_ID = "recommendations/blueprint/configurations/";
+  protected static final String CONFIGURATIONS_PROPERTY_ID = "recommendations/blueprint/configurations/";
 
-  private Map<String, Map<String, Map<String, String>>> calculateConfigurations(Request request) {
+  protected Map<String, Map<String, Map<String, String>>> calculateConfigurations(Request request) {
     Map<String, Map<String, Map<String, String>>> configurations = new HashMap<String, Map<String, Map<String, String>>>();
     Map<String, Object> properties = request.getProperties().iterator().next();
     for (String property : properties.keySet()) {
@@ -202,7 +202,7 @@ public abstract class StackAdvisorResourceProvider extends ReadOnlyResourceProvi
             siteMap.put(propertiesProperty, propertiesMap);
           }
 
-          String value = (String) properties.get(property);
+          String value = properties.get(property).toString();
           propertiesMap.put(propertyName, value);
         } catch (Exception e) {
           LOG.debug(String.format("Error handling configuration property, name = %s", property), e);

+ 2 - 0
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java

@@ -1005,6 +1005,8 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog {
     result.put("zookeeper_keytab_path","zookeeper-env");
     result.put("storm_principal_name","storm-env");
     result.put("storm_keytab","storm-env");
+    result.put("hive_hostname","hive-env");
+    result.put("oozie_hostname","oozie-env");
 
     return result;
   }

+ 120 - 0
ambari-server/src/main/java/org/apache/ambari/server/view/ViewArchiveUtility.java

@@ -0,0 +1,120 @@
+/**
+ * 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.view;
+
+import org.apache.ambari.server.view.configuration.ViewConfig;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.JarFile;
+
+/**
+ * Helper class for basic view archive utility.
+ */
+public class ViewArchiveUtility {
+
+  /**
+   * Constants
+   */
+  private static final String VIEW_XML = "view.xml";
+
+
+  // ----- ViewArchiveUtility ------------------------------------------------
+
+  /**
+   * Get the view configuration from the given archive file.
+   *
+   * @param archiveFile  the archive file
+   *
+   * @return the associated view configuration
+   */
+  public ViewConfig getViewConfigFromArchive(File archiveFile)
+      throws MalformedURLException, JAXBException {
+    ClassLoader cl = URLClassLoader.newInstance(new URL[]{archiveFile.toURI().toURL()});
+
+    InputStream configStream      = cl.getResourceAsStream(VIEW_XML);
+    JAXBContext jaxbContext       = JAXBContext.newInstance(ViewConfig.class);
+    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+
+    return (ViewConfig) jaxbUnmarshaller.unmarshal(configStream);
+  }
+
+  /**
+   * Get the view configuration from the extracted archive file.
+   *
+   * @param archivePath path to extracted archive
+   *
+   * @return the associated view configuration
+   *
+   * @throws JAXBException if xml is malformed
+   * @throws java.io.FileNotFoundException if xml was not found
+   */
+  public ViewConfig getViewConfigFromExtractedArchive(String archivePath)
+      throws JAXBException, FileNotFoundException {
+
+    InputStream configStream      = new FileInputStream(new File(archivePath + File.separator + VIEW_XML));
+    JAXBContext  jaxbContext      = JAXBContext.newInstance(ViewConfig.class);
+    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+
+    return (ViewConfig) jaxbUnmarshaller.unmarshal(configStream);
+  }
+
+  /**
+   * Get a new file instance for the given path.
+   *
+   * @param path  the path
+   *
+   * @return a new file instance
+   */
+  public File getFile(String path) {
+    return new File(path);
+  }
+
+  /**
+   * Get a new file output stream for the given file.
+   *
+   * @param file  the file
+   *
+   * @return a new file output stream
+   */
+  public FileOutputStream getFileOutputStream(File file) throws FileNotFoundException {
+    return new FileOutputStream(file);
+  }
+
+  /**
+   * Get a new jar file instance from the given file.
+   *
+   * @param file  the file
+   *
+   * @return a new jar file instance
+   */
+  public JarFile getJarFile(File file) throws IOException {
+    return new JarFile(file);
+  }
+}

+ 223 - 0
ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java

@@ -0,0 +1,223 @@
+/**
+ * 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.view;
+
+import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Extractor for view archives.
+ */
+public class ViewExtractor {
+
+  /**
+   * Constants
+   */
+  private static final String ARCHIVE_CLASSES_DIR = "WEB-INF/classes";
+  private static final String ARCHIVE_LIB_DIR     = "WEB-INF/lib";
+
+  @Inject
+  ViewArchiveUtility archiveUtility;
+
+  /**
+   * The logger.
+   */
+  protected final static Logger LOG = LoggerFactory.getLogger(ViewExtractor.class);
+
+
+  // ----- ViewExtractor -----------------------------------------------------
+
+  /**
+   * Extract the given view archive to the given archive directory.
+   *
+   * @param view         the view entity
+   * @param viewArchive  the view archive file
+   * @param archiveDir   the view archive directory
+   *
+   * @return the class loader for the archive classes
+   *
+   * @throws ExtractionException if the archive can not be extracted
+   */
+  public ClassLoader extractViewArchive(ViewEntity view, File viewArchive, File archiveDir)
+      throws ExtractionException {
+
+    String archivePath = archiveDir.getAbsolutePath();
+
+    try {
+      // Skip if the archive has already been extracted
+      if (!archiveDir.exists()) {
+
+        String msg = "Creating archive folder " + archivePath + ".";
+
+        view.setStatusDetail(msg);
+        LOG.info(msg);
+
+        if (archiveDir.mkdir()) {
+          JarFile viewJarFile = archiveUtility.getJarFile(viewArchive);
+          Enumeration enumeration = viewJarFile.entries();
+
+          msg = "Extracting files from " + viewArchive.getName() + ".";
+
+          view.setStatusDetail(msg);
+          LOG.info(msg);
+
+          while (enumeration.hasMoreElements()) {
+            JarEntry jarEntry  = (JarEntry) enumeration.nextElement();
+            String   entryPath = archivePath + File.separator + jarEntry.getName();
+
+            File entryFile = archiveUtility.getFile(entryPath);
+
+            if (jarEntry.isDirectory()) {
+              if (!entryFile.mkdir()) {
+                msg = "Could not create archive entry directory " + entryPath + ".";
+
+                view.setStatusDetail(msg);
+                LOG.error(msg);
+                throw new ExtractionException(msg);
+              }
+            } else {
+              InputStream is = viewJarFile.getInputStream(jarEntry);
+              try {
+                FileOutputStream fos = archiveUtility.getFileOutputStream(entryFile);
+                try {
+                  while (is.available() > 0) {
+                    fos.write(is.read());
+                  }
+                } finally {
+                  fos.close();
+                }
+              } finally {
+                is.close();
+              }
+            }
+          }
+        } else {
+          msg = "Could not create archive directory " + archivePath + ".";
+
+          view.setStatusDetail(msg);
+          LOG.error(msg);
+          throw new ExtractionException(msg);
+        }
+      }
+      return getArchiveClassLoader(archiveDir);
+
+    } catch (Exception e) {
+      String msg = "Caught exception trying to extract the view archive " + archivePath + ".";
+
+      view.setStatusDetail(msg);
+      LOG.error(msg, e);
+      throw new ExtractionException(msg, e);
+    }
+  }
+
+  /**
+   * Ensure that the extracted view archive directory exists.
+   *
+   * @param extractedArchivesPath  the path
+   *
+   * @return false if the directory does not exist and can not be created
+   */
+  public boolean ensureExtractedArchiveDirectory(String extractedArchivesPath) {
+
+    File extractedArchiveDir = archiveUtility.getFile(extractedArchivesPath);
+
+    return extractedArchiveDir.exists() || extractedArchiveDir.mkdir();
+  }
+
+
+  // ----- archiveUtility methods ----------------------------------------------------
+
+  // get a class loader for the given archive directory
+  private ClassLoader getArchiveClassLoader(File archiveDir)
+      throws MalformedURLException {
+
+    String    archivePath = archiveDir.getAbsolutePath();
+    List<URL> urlList     = new LinkedList<URL>();
+
+    // include the classes directory
+    String classesPath = archivePath + File.separator + ARCHIVE_CLASSES_DIR;
+    File   classesDir  = archiveUtility.getFile(classesPath);
+    if (classesDir.exists()) {
+      urlList.add(classesDir.toURI().toURL());
+    }
+
+    // include any libraries in the lib directory
+    String libPath = archivePath + File.separator + ARCHIVE_LIB_DIR;
+    File   libDir  = archiveUtility.getFile(libPath);
+    if (libDir.exists()) {
+      File[] files = libDir.listFiles();
+      if (files != null) {
+        for (final File fileEntry : files) {
+          if (!fileEntry.isDirectory()) {
+            urlList.add(fileEntry.toURI().toURL());
+          }
+        }
+      }
+    }
+
+    // include the archive directory
+    urlList.add(archiveDir.toURI().toURL());
+
+    return URLClassLoader.newInstance(urlList.toArray(new URL[urlList.size()]));
+  }
+
+
+  // ----- inner class : ExtractionException ---------------------------------
+
+  /**
+   * General exception for view archive extraction.
+   */
+  public static class ExtractionException extends Exception {
+
+    // ----- Constructors ----------------------------------------------------
+
+    /**
+     * Construct an extraction exception.
+     *
+     * @param msg  the exception message
+     */
+    public ExtractionException(String msg) {
+      super(msg);
+    }
+
+    /**
+     * Construct an extraction exception.
+     *
+     * @param msg        the exception message
+     * @param throwable  the root cause
+     */
+    public ExtractionException(String msg, Throwable throwable) {
+      super(msg, throwable);
+    }
+  }
+}

+ 132 - 297
ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java

@@ -18,46 +18,17 @@
 
 package org.apache.ambari.server.view;
 
-import java.beans.IntrospectionException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-
 import com.google.common.collect.Sets;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
 import org.apache.ambari.server.api.resources.SubResourceDefinition;
 import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition;
 import org.apache.ambari.server.api.services.ViewExternalSubResourceService;
 import org.apache.ambari.server.api.services.ViewSubResourceService;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.ControllerModule;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.orm.dao.MemberDAO;
 import org.apache.ambari.server.orm.dao.PrivilegeDAO;
@@ -103,9 +74,22 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.core.GrantedAuthority;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import java.beans.IntrospectionException;
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Registry for view and view instance definitions.
@@ -116,9 +100,6 @@ public class ViewRegistry {
   /**
    * Constants
    */
-  private static final String VIEW_XML = "view.xml";
-  private static final String ARCHIVE_CLASSES_DIR = "WEB-INF/classes";
-  private static final String ARCHIVE_LIB_DIR = "WEB-INF/lib";
   private static final String EXTRACTED_ARCHIVES_DIR = "work";
 
   /**
@@ -149,11 +130,6 @@ public class ViewRegistry {
   private final Map<String, Set<Listener>> listeners =
       new ConcurrentHashMap<String, Set<Listener>>();
 
-  /**
-   * Helper class.
-   */
-  private ViewRegistryHelper helper = new ViewRegistryHelper();
-
   /**
    * The singleton view registry instance.
    */
@@ -224,9 +200,36 @@ public class ViewRegistry {
   @Inject
   ViewInstanceHandlerList handlerList;
 
+  /**
+   * The view extractor;
+   */
+  @Inject
+  ViewExtractor extractor;
+
+  /**
+   * The view archive utility.
+   */
+  @Inject
+  ViewArchiveUtility archiveUtility;
+
 
   // ----- ViewRegistry ------------------------------------------------------
 
+  /**
+   * Registry main method.
+   *
+   * @param args  the command line arguments
+   *
+   * @throws Exception if the registry command can not be completed
+   */
+  public static void main(String[] args) throws Exception {
+
+    Injector injector = Guice.createInjector(new ControllerModule());
+    initInstance(injector.getInstance(ViewRegistry.class));
+
+    singleton.readViewArchives(true, false);
+  }
+
   /**
    * Get the collection of all the view definitions.
    *
@@ -396,56 +399,10 @@ public class ViewRegistry {
   }
 
   /**
-   * Asynchronously read the view archives.
+   * Read the view archives.
    */
   public void readViewArchives() {
-
-    final ExecutorService executorService = getExecutorService(configuration);
-
-    // submit a task to manage the extraction tasks
-    executorService.submit(new Runnable() {
-      @Override
-      public void run() {
-
-        try {
-          File viewDir = configuration.getViewsDir();
-
-          String extractedArchivesPath = viewDir.getAbsolutePath() +
-              File.separator + EXTRACTED_ARCHIVES_DIR;
-
-          if (ensureExtractedArchiveDirectory(extractedArchivesPath)) {
-            File[] files = viewDir.listFiles();
-
-            if (files != null) {
-              for (final File archiveFile : files) {
-                if (!archiveFile.isDirectory()) {
-
-                  final ViewConfig viewConfig = helper.getViewConfigFromArchive(archiveFile);
-
-                  String commonName = viewConfig.getName();
-                  String version    = viewConfig.getVersion();
-                  String viewName   = ViewEntity.getViewName(commonName, version);
-
-                  final String     archivePath    = extractedArchivesPath + File.separator + viewName;
-                  final ViewEntity viewDefinition = new ViewEntity(viewConfig, configuration, archivePath);
-
-                  // submit a new task for each archive being read
-                  executorService.submit(new Runnable() {
-                    @Override
-                    public void run() {
-                      readViewArchive(viewDefinition, archiveFile, archivePath, viewConfig);
-                    }
-                  });
-                }
-              }
-              removeUndeployedViews();
-            }
-          }
-        } catch (Exception e) {
-          LOG.error("Caught exception reading view archives.", e);
-        }
-      }
-    });
+    readViewArchives(false, true);
   }
 
   /**
@@ -757,15 +714,6 @@ public class ViewRegistry {
     listeners.clear();
   }
 
-  /**
-   * Set the helper.
-   *
-   * @param helper  the helper
-   */
-  protected void setHelper(ViewRegistryHelper helper) {
-    this.helper = helper;
-  }
-
   // get a view entity for the given internal view name
   private ViewEntity getDefinition(String viewName) {
     return viewDefinitions.get(viewName);
@@ -1115,110 +1063,6 @@ public class ViewRegistry {
     return resourceEntity;
   }
 
-  // ensure that the extracted view archive directory exists
-  private boolean ensureExtractedArchiveDirectory(String extractedArchivesPath) {
-    File extractedArchiveDir = helper.getFile(extractedArchivesPath);
-
-    if (!extractedArchiveDir.exists()) {
-      if (!extractedArchiveDir.mkdir()) {
-        LOG.error("Could not create extracted view archive directory " +
-            extractedArchivesPath + ".");
-        return false;
-      }
-    }
-    return true;
-  }
-
-  // extract the given view archive to the given archive directory
-  private ClassLoader extractViewArchive(ViewEntity viewDefinition, File viewArchive, File archiveDir)
-      throws IOException {
-
-    // Skip if the archive has already been extracted
-    if (!archiveDir.exists()) {
-
-      String archivePath = archiveDir.getAbsolutePath();
-
-      String msg = "Creating archive folder " + archivePath + ".";
-      LOG.info(msg);
-      setViewStatus(viewDefinition, ViewDefinition.ViewStatus.LOADING, msg);
-
-      if (archiveDir.mkdir()) {
-        JarFile     viewJarFile = helper.getJarFile(viewArchive);
-        Enumeration enumeration = viewJarFile.entries();
-
-        msg = "Extracting files from " + viewArchive.getName() + ":";
-        LOG.info(msg);
-        setViewStatus(viewDefinition, ViewDefinition.ViewStatus.LOADING, msg);
-
-        while (enumeration.hasMoreElements()) {
-          JarEntry jarEntry  = (JarEntry) enumeration.nextElement();
-          String   entryPath = archivePath + File.separator + jarEntry.getName();
-
-          LOG.info("    " + entryPath);
-
-          File entryFile = helper.getFile(entryPath);
-
-          if (jarEntry.isDirectory()) {
-            if (!entryFile.mkdir()) {
-              LOG.error("Could not create archive entry directory " + entryPath + ".");
-            }
-          } else {
-            InputStream is = viewJarFile.getInputStream(jarEntry);
-            try {
-              FileOutputStream fos = helper.getFileOutputStream(entryFile);
-              try {
-                while (is.available() > 0) {
-                  fos.write(is.read());
-                }
-              } finally {
-                fos.close();
-              }
-            } finally {
-              is.close();
-            }
-          }
-        }
-      } else {
-        LOG.error("Could not create archive directory " + archivePath + ".");
-      }
-    }
-    return getArchiveClassLoader(archiveDir);
-  }
-
-  // get a class loader for the given archive directory
-  private ClassLoader getArchiveClassLoader(File archiveDir)
-      throws MalformedURLException {
-
-    String    archivePath = archiveDir.getAbsolutePath();
-    List<URL> urlList     = new LinkedList<URL>();
-
-    // include the classes directory
-    String classesPath = archivePath + File.separator + ARCHIVE_CLASSES_DIR;
-    File   classesDir  = helper.getFile(classesPath);
-    if (classesDir.exists()) {
-      urlList.add(classesDir.toURI().toURL());
-    }
-
-    // include any libraries in the lib directory
-    String libPath = archivePath + File.separator + ARCHIVE_LIB_DIR;
-    File   libDir  = helper.getFile(libPath);
-    if (libDir.exists()) {
-      File[] files = libDir.listFiles();
-      if (files != null) {
-        for (final File fileEntry : files) {
-          if (!fileEntry.isDirectory()) {
-            urlList.add(fileEntry.toURI().toURL());
-          }
-        }
-      }
-    }
-
-    // include the archive directory
-    urlList.add(archiveDir.toURI().toURL());
-
-    return URLClassLoader.newInstance(urlList.toArray(new URL[urlList.size()]));
-  }
-
   // notify the view identified by the given view name of the given event
   private void fireEvent(Event event, String viewName) {
     Set<Listener> listeners = this.listeners.get(viewName);
@@ -1265,22 +1109,94 @@ public class ViewRegistry {
     }
   }
 
-  // read a view archive and return the set of new view instances
+
+  // read the view archives.
+  private void readViewArchives(boolean systemOnly, boolean useExecutor) {
+    try {
+      File viewDir = configuration.getViewsDir();
+
+      String extractedArchivesPath = viewDir.getAbsolutePath() +
+          File.separator + EXTRACTED_ARCHIVES_DIR;
+
+      if (extractor.ensureExtractedArchiveDirectory(extractedArchivesPath)) {
+
+        File[] files  = viewDir.listFiles();
+
+        if (files != null) {
+
+          Set<Runnable> extractionRunnables = new HashSet<Runnable>();
+
+          for (final File archiveFile : files) {
+            if (!archiveFile.isDirectory()) {
+
+              final ViewConfig viewConfig = archiveUtility.getViewConfigFromArchive(archiveFile);
+
+              String commonName = viewConfig.getName();
+              String version    = viewConfig.getVersion();
+              String viewName   = ViewEntity.getViewName(commonName, version);
+
+              final String extractedArchiveDirPath = extractedArchivesPath + File.separator + viewName;
+              final File extractedArchiveDirFile = archiveUtility.getFile(extractedArchiveDirPath);
+
+              final ViewEntity viewDefinition = new ViewEntity(viewConfig, configuration, extractedArchiveDirPath);
+
+              boolean systemView = viewDefinition.isSystem();
+
+              if (!systemOnly || systemView) {
+                // update the registry with the view
+                addDefinition(viewDefinition);
+
+                // always load system views up front
+                if (systemView || !useExecutor || extractedArchiveDirFile.exists()) {
+                  // if the archive is already extracted then load the view now
+                  readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile, viewConfig);
+                } else {
+                  // if the archive needs to be extracted then create a runnable to do it
+                  extractionRunnables.add(new Runnable() {
+                    @Override
+                    public void run() {
+                      readViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile, viewConfig);
+                    }
+                  });
+                }
+              }
+            }
+          }
+
+          if (useExecutor && extractionRunnables.size() > 0) {
+            final ExecutorService executorService = getExecutorService(configuration);
+
+            for (Runnable runnable : extractionRunnables) {
+              // submit a new task for each archive that needs extraction
+              executorService.submit(runnable);
+            }
+          }
+
+          removeUndeployedViews();
+        }
+      } else {
+        LOG.error("Could not create extracted view archive directory " + extractedArchivesPath + ".");
+      }
+    } catch (Exception e) {
+      LOG.error("Caught exception reading view archives.", e);
+    }
+  }
+
+  // read a view archive
   private void readViewArchive(ViewEntity viewDefinition,
                                                   File archiveFile,
-                                                  String archivePath,
+                                                  File extractedArchiveDirFile,
                                                   ViewConfig viewConfig) {
 
-    setViewStatus(viewDefinition, ViewEntity.ViewStatus.LOADING, "Loading " + archivePath + ".");
+    setViewStatus(viewDefinition, ViewEntity.ViewStatus.LOADING, "Loading " + extractedArchiveDirFile + ".");
 
-    try {
-      // update the registry with the view
-      addDefinition(viewDefinition);
+    String extractedArchiveDirPath = extractedArchiveDirFile.getAbsolutePath();
 
+    try {
       // extract the archive and get the class loader
-      ClassLoader cl = extractViewArchive(viewDefinition, archiveFile, helper.getFile(archivePath));
+      ClassLoader cl = extractor.extractViewArchive(viewDefinition, archiveFile, extractedArchiveDirFile);
 
-      viewConfig = helper.getViewConfigFromExtractedArchive(archivePath);
+      viewConfig = archiveUtility.getViewConfigFromExtractedArchive(extractedArchiveDirPath);
 
       setupViewDefinition(viewDefinition, viewConfig, cl);
 
@@ -1301,12 +1217,12 @@ public class ViewRegistry {
         addInstanceDefinition(viewDefinition, instanceEntity);
         handlerList.addViewInstance(instanceEntity);
       }
-      setViewStatus(viewDefinition, ViewEntity.ViewStatus.LOADED, "Loaded " + archivePath + ".");
+      setViewStatus(viewDefinition, ViewEntity.ViewStatus.LOADED, "Loaded " + extractedArchiveDirPath + ".");
 
     } catch (Exception e) {
-      String msg = "Caught exception loading view " + viewDefinition.getViewName() + " : " + e.getMessage();
+      String msg = "Caught exception loading view " + viewDefinition.getViewName();
 
-      setViewStatus(viewDefinition, ViewEntity.ViewStatus.ERROR, msg);
+      setViewStatus(viewDefinition, ViewEntity.ViewStatus.ERROR, msg + " : " + e.getMessage());
       LOG.error(msg, e);
     }
   }
@@ -1334,85 +1250,4 @@ public class ViewRegistry {
     }
     return executorService;
   }
-
-
-
-  // ----- inner class : ViewRegistryHelper ----------------------------------
-
-  /**
-   * Registry helper class.
-   */
-  protected static class ViewRegistryHelper {
-
-    /**
-     * Get the view configuration from the given archive file.
-     *
-     * @param archiveFile  the archive file
-     *
-     * @return the associated view configuration
-     */
-    public ViewConfig getViewConfigFromArchive(File archiveFile)
-        throws MalformedURLException, JAXBException {
-      ClassLoader cl = URLClassLoader.newInstance(new URL[]{archiveFile.toURI().toURL()});
-
-      InputStream  configStream     = cl.getResourceAsStream(VIEW_XML);
-      JAXBContext  jaxbContext      = JAXBContext.newInstance(ViewConfig.class);
-      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
-
-      return (ViewConfig) jaxbUnmarshaller.unmarshal(configStream);
-    }
-
-    /**
-     * Get the view configuration from the extracted archive file.
-     *
-     * @param archivePath path to extracted archive
-     *
-     * @return the associated view configuration
-     *
-     * @throws JAXBException if xml is malformed
-     * @throws FileNotFoundException if xml was not found
-     */
-    public ViewConfig getViewConfigFromExtractedArchive(String archivePath)
-        throws JAXBException, FileNotFoundException {
-
-      InputStream configStream      = new FileInputStream(new File(archivePath + File.separator + VIEW_XML));
-      JAXBContext  jaxbContext      = JAXBContext.newInstance(ViewConfig.class);
-      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
-
-      return (ViewConfig) jaxbUnmarshaller.unmarshal(configStream);
-    }
-
-    /**
-     * Get a new file instance for the given path.
-     *
-     * @param path  the path
-     *
-     * @return a new file instance
-     */
-    public File getFile(String path) {
-      return new File(path);
-    }
-
-    /**
-     * Get a new file output stream for the given file.
-     *
-     * @param file  the file
-     *
-     * @return a new file output stream
-     */
-    public FileOutputStream getFileOutputStream(File file) throws FileNotFoundException {
-      return new FileOutputStream(file);
-    }
-
-    /**
-     * Get a new jar file instance from the given file.
-     *
-     * @param file  the file
-     *
-     * @return a new jar file instance
-     */
-    public JarFile getJarFile(File file) throws IOException {
-      return new JarFile(file);
-    }
-  }
 }

+ 85 - 15
ambari-server/src/main/python/ambari-server.py

@@ -185,6 +185,14 @@ STACK_UPGRADE_HELPER_CMD = "{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
                           os.pathsep + "{2} " +\
                           "org.apache.ambari.server.upgrade.StackUpgradeHelper" +\
                           " {3} {4} > " + SERVER_OUT_FILE + " 2>&1"
+
+
+VIEW_EXTRACT_CMD = "{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
+                          os.pathsep + "{2} " +\
+                          "org.apache.ambari.server.view.ViewRegistry " +\
+                          "> " + SERVER_OUT_FILE + " 2>&1"
+
+
 ULIMIT_CMD = "ulimit -n"
 SERVER_INIT_TIMEOUT = 5
 SERVER_START_TIMEOUT = 10
@@ -304,7 +312,7 @@ DATABASE_INDEX = 0
 PROMPT_DATABASE_OPTIONS = False
 USERNAME_PATTERN = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
 PASSWORD_PATTERN = "^[a-zA-Z0-9_-]*$"
-DATABASE_NAMES = ["postgres", "oracle", "mysql"]
+DATABASE_TYPES = ["postgres", "oracle", "mysql"]
 DATABASE_STORAGE_NAMES = ["Database", "Service", "Database"]
 DATABASE_PORTS = ["5432", "1521", "3306"]
 DATABASE_DRIVER_NAMES = ["org.postgresql.Driver", "oracle.jdbc.driver.OracleDriver", "com.mysql.jdbc.Driver"]
@@ -838,8 +846,6 @@ def restart_postgres():
   return 0, "", ""
 
 
-# todo: check if the scheme is already exist
-
 def write_property(key, value):
   conf_file = find_properties_file()
   properties = Properties()
@@ -1087,7 +1093,7 @@ def get_pass_file_path(conf_file):
 # Set database properties to default values
 def load_default_db_properties(args):
   args.persistence_type = 'local'
-  args.dbms = DATABASE_NAMES[DATABASE_INDEX]
+  args.dbms = DATABASE_TYPES[DATABASE_INDEX]
   args.database_host = "localhost"
   args.database_port = DATABASE_PORTS[DATABASE_INDEX]
   args.database_name = DEFAULT_DB_NAME
@@ -1141,7 +1147,7 @@ def prompt_db_properties(args):
       pass
 
       DATABASE_INDEX = args.database_index
-      args.dbms = DATABASE_NAMES[args.database_index]
+      args.dbms = DATABASE_TYPES[args.database_index]
 
       if args.persistence_type != 'local':
         args.database_host = get_validated_string_input(
@@ -1217,6 +1223,21 @@ def prompt_db_properties(args):
     password=args.database_password
   ))
 
+# extract the system views
+def extract_views():
+  jdk_path = find_jdk()
+  if jdk_path is None:
+    print_error_msg("No JDK found, please run the \"setup\" "
+                    "command to install a JDK automatically or install any "
+                    "JDK manually to " + JDK_INSTALL_DIR)
+    return 1
+
+  command = VIEW_EXTRACT_CMD.format(jdk_path, get_conf_dir(),
+    get_ambari_classpath())
+  (retcode, stdout, stderr) = run_os_command(command)
+  print_info_msg("Return code from view extraction: " +
+                 str(retcode))
+  return retcode
 
 # Store set of properties for remote database connection
 def store_remote_properties(args):
@@ -1386,12 +1407,48 @@ def configure_database_password(showDefault=True):
   return password
 
 
-def check_database_name_property():
+def get_ambari_version(properties):
+  """
+  :param properties: Ambari properties
+  :return: Return a string of the ambari version. When comparing versions, please use "compare_versions" function.
+  """
+  version = None
+  try:
+    server_version_file_path = properties[SERVER_VERSION_FILE_PATH]
+    if server_version_file_path and os.path.exists(server_version_file_path):
+      with open(server_version_file_path, 'r') as file:
+        version = file.read().strip()
+  except:
+    print_error_msg("Error getting ambari version")
+  return version
+
+
+def check_database_name_property(args, upgrade=False):
+  """
+  :param upgrade: If Ambari is being upgraded.
+  :return:
+  """
   properties = get_ambari_properties()
   if properties == -1:
     print_error_msg("Error getting ambari properties")
     return -1
 
+  version = get_ambari_version(properties)
+  if upgrade and compare_versions(version, "1.7.0") >= 0:
+
+    expected_db_name = properties[JDBC_DATABASE_NAME_PROPERTY]
+    # The existing ambari config file is probably from an earlier version of Ambari, and needs to be transformed.
+    if expected_db_name is None or expected_db_name == "":
+      db_name = properties[JDBC_DATABASE_PROPERTY]
+
+      if db_name:
+        write_property(JDBC_DATABASE_NAME_PROPERTY, db_name)
+        remove_property(JDBC_DATABASE_PROPERTY)
+        properties = get_ambari_properties()
+      else:
+        err = "DB Name property not set in config file.\n" + SETUP_OR_UPGRADE_MSG
+        raise FatalException(-1, "Upgrade to version %s cannot transform config file." % str(version))
+
   dbname = properties[JDBC_DATABASE_NAME_PROPERTY]
   if dbname is None or dbname == "":
     err = "DB Name property not set in config file.\n" + SETUP_OR_UPGRADE_MSG
@@ -1523,7 +1580,7 @@ def parse_properties_file(args):
     args.database_port = properties[JDBC_PORT_PROPERTY]
     global DATABASE_INDEX
     try:
-      DATABASE_INDEX = DATABASE_NAMES.index(args.dbms)
+      DATABASE_INDEX = DATABASE_TYPES.index(args.dbms)
     except ValueError:
       pass
 
@@ -2224,6 +2281,12 @@ def setup(args):
       raise FatalException(retcode, err)
     check_jdbc_drivers(args)
 
+  print 'Extracting system views...'
+  retcode = extract_views()
+  if not retcode == 0:
+    err = 'Error while extracting system views. Exiting'
+    raise FatalException(retcode, err)
+
 
 def proceedJDBCProperties(args):
   if not os.path.isfile(args.jdbc_driver):
@@ -2297,7 +2360,7 @@ def reset(args):
     err = "Ambari Server 'reset' cancelled"
     raise FatalException(1, err)
 
-  check_database_name_property()
+  check_database_name_property(args)
   parse_properties_file(args)
 
   if args.persistence_type == "remote":
@@ -2370,7 +2433,7 @@ def start(args):
           "command as root, as sudo or as user \"{1}\"".format(current_user, ambari_user)
     raise FatalException(1, err)
 
-  check_database_name_property()
+  check_database_name_property(args)
   parse_properties_file(args)
 
   status, pid = is_server_runing()
@@ -2540,7 +2603,7 @@ def upgrade_stack(args, stack_id, repo_url=None, repo_url_os=None):
     err = 'Ambari-server upgradestack should be run with ' \
           'root-level privileges'
     raise FatalException(4, err)
-  check_database_name_property()
+  check_database_name_property(args)
 
   stack_name, stack_version = stack_id.split(STACK_NAME_VER_SEP)
   retcode = run_stack_upgrade(stack_name, stack_version, repo_url, repo_url_os)
@@ -2726,7 +2789,7 @@ def upgrade(args):
     raise FatalException(retcode, err)
 
   try:
-    check_database_name_property()
+    check_database_name_property(args, upgrade=True)
   except FatalException:
     properties = get_ambari_properties()
     if properties == -1:
@@ -4170,12 +4233,12 @@ def main():
     options.database_index = 0
     DATABASE_INDEX = 0
     pass
-  elif options.dbms is not None and options.dbms not in DATABASE_NAMES:
+  elif options.dbms is not None and options.dbms not in DATABASE_TYPES:
     parser.print_help()
     parser.error("Unsupported Database " + options.dbms)
   elif options.dbms is not None:
     options.dbms = options.dbms.lower()
-    DATABASE_INDEX = DATABASE_NAMES.index(options.dbms)
+    DATABASE_INDEX = DATABASE_TYPES.index(options.dbms)
 
   #correct port
   if options.database_port is not None:
@@ -4339,6 +4402,9 @@ class Properties(object):
       self.process_pair(key, value)
 
   def process_pair(self, key, value):
+    """
+    Adds or overrides the property with the given key.
+    """
     oldkey = key
     oldvalue = value
     keyparts = self.bspacere.split(key)
@@ -4407,7 +4473,9 @@ class Properties(object):
 
   def store(self, out, header=""):
     """ Write the properties list to the stream 'out' along
-    with the optional 'header' """
+    with the optional 'header'
+    This function will attempt to close the file handler once it's done.
+    """
     if out.mode[0] != 'w':
       raise ValueError, 'Steam should be opened in write mode!'
     try:
@@ -4420,9 +4488,11 @@ class Properties(object):
       for prop, val in self._origprops.items():
         if val is not None:
           out.write(''.join((prop, '=', val, '\n')))
-      out.close()
     except IOError:
       raise
+    finally:
+      if out:
+        out.close()
 
 if __name__ == "__main__":
   try:

+ 40 - 0
ambari-server/src/main/resources/ganglia_properties.json

@@ -1649,6 +1649,26 @@
         "pointInTime":false,
         "temporal":true
       },
+      "metrics/dfs/FSNamesystem/CapacityRemaining":{
+        "metric":"dfs.FSNamesystem.CapacityRemaining",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityTotal":{
+        "metric":"dfs.FSNamesystem.CapacityTotal",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityUsed":{
+        "metric":"dfs.FSNamesystem.CapacityUsed",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityNonDFSUsed": {
+        "metric": "dfs.FSNamesystem.CapacityUsedNonDFS",
+        "pointInTime": false,
+        "temporal": true
+      },
       "metrics/dfs/FSNamesystem/CorruptBlocks":{
         "metric":"dfs.FSNamesystem.CorruptBlocks",
         "pointInTime":false,
@@ -11115,6 +11135,26 @@
         "pointInTime":false,
         "temporal":true
       },
+      "metrics/dfs/FSNamesystem/CapacityRemaining":{
+        "metric":"dfs.FSNamesystem.CapacityRemaining",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityTotal":{
+        "metric":"dfs.FSNamesystem.CapacityTotal",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityUsed":{
+        "metric":"dfs.FSNamesystem.CapacityUsed",
+        "pointInTime":false,
+        "temporal":true
+      },
+      "metrics/dfs/FSNamesystem/CapacityNonDFSUsed": {
+        "metric": "dfs.FSNamesystem.CapacityUsedNonDFS",
+        "pointInTime": false,
+        "temporal": true
+      },
       "metrics/dfs/FSNamesystem/CorruptBlocks":{
         "metric":"dfs.FSNamesystem.CorruptBlocks",
         "pointInTime":false,

+ 15 - 5
ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/params.py

@@ -19,17 +19,29 @@ limitations under the License.
 
 from resource_management import *
 from resource_management.core.system import System
-import os
 
 config = Script.get_config()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_conf_empty_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf.empty")
+  mapreduce_libs_path = format("/usr/hdp/{rpm_version}/hadoop-mapreduce/*")
+  hadoop_libexec_dir = format("/usr/hdp/{rpm_version}/hadoop/libexec")
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_conf_empty_dir = "/etc/hadoop/conf.empty"
+  mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
+  hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
+
 #security params
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 #java params
 java_home = config['hostLevelParams']['java_home']
 #hadoop params
-hadoop_conf_dir = "/etc/hadoop/conf"
-hadoop_conf_empty_dir = "/etc/hadoop/conf.empty"
 hdfs_log_dir_prefix = config['configurations']['hadoop-env']['hdfs_log_dir_prefix']
 hadoop_pid_dir_prefix = config['configurations']['hadoop-env']['hadoop_pid_dir_prefix']
 hadoop_root_logger = config['configurations']['hadoop-env']['hadoop_root_logger']
@@ -56,8 +68,6 @@ ttnode_heapsize = "1024m"
 
 dtnode_heapsize = config['configurations']['hadoop-env']['dtnode_heapsize']
 mapred_pid_dir_prefix = default("/configurations/mapred-env/mapred_pid_dir_prefix","/var/run/hadoop-mapreduce")
-mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
-hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
 mapred_log_dir_prefix = default("/configurations/mapred-env/mapred_log_dir_prefix","/var/log/hadoop-mapreduce")
 
 #users and groups

+ 2 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-INSTALL/scripts/params.py

@@ -19,7 +19,6 @@ limitations under the License.
 
 from resource_management import *
 from resource_management.core.system import System
-import os
 import json
 import collections
 
@@ -38,6 +37,8 @@ user_group = config['configurations']['cluster-env']['user_group']
 proxyuser_group = default("/configurations/hadoop-env/proxyuser_group","users")
 nagios_group = config['configurations']['nagios-env']['nagios_group']
 
+hdfs_log_dir_prefix = config['configurations']['hadoop-env']['hdfs_log_dir_prefix']
+
 #hosts
 hostname = config["hostname"]
 ambari_server_hostname = config['clusterHostInfo']['ambari_server_host'][0]

+ 3 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/files/checkForFormat.sh

@@ -24,6 +24,8 @@ export hdfs_user=$1
 shift
 export conf_dir=$1
 shift
+export bin_dir=$1
+shift
 export mark_dir=$1
 shift
 export name_dirs=$*
@@ -50,6 +52,7 @@ if [[ ! -d $mark_dir ]] ; then
   done
 
   if [[ $EXIT_CODE == 0 ]] ; then
+    export PATH=$PATH:$bin_dir
     su - ${hdfs_user} -c "yes Y | hadoop --config ${conf_dir} ${command}"
   else
     echo "ERROR: Namenode directory(s) is non empty. Will not format the namenode. List of non-empty namenode dirs ${list_of_non_empty_dirs}"

+ 19 - 6
ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py

@@ -23,6 +23,25 @@ import os
 
 config = Script.get_config()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  mapreduce_libs_path = format("/usr/hdp/{rpm_version}/hadoop-mapreduce/*")
+  hadoop_libexec_dir = format("/usr/hdp/{rpm_version}/hadoop/libexec")
+  hadoop_lib_home = format("/usr/hdp/{rpm_version}/hadoop/lib")
+  hadoop_bin = format("/usr/hdp/{rpm_version}/hadoop/sbin")
+  hadoop_home = format('/usr/hdp/{rpm_version}/hadoop')
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
+  hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
+  hadoop_lib_home = "/usr/lib/hadoop/lib"
+  hadoop_bin = "/usr/lib/hadoop/sbin"
+  hadoop_home = '/usr'
+
 #security params
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 
@@ -72,11 +91,7 @@ if has_ganglia_server:
 
 if has_namenode:
   hadoop_tmp_dir = format("/tmp/hadoop-{hdfs_user}")
-hadoop_lib_home = "/usr/lib/hadoop/lib"
-hadoop_conf_dir = "/etc/hadoop/conf"
 hadoop_pid_dir_prefix = config['configurations']['hadoop-env']['hadoop_pid_dir_prefix']
-hadoop_home = "/usr"
-hadoop_bin = "/usr/lib/hadoop/sbin"
 
 task_log4j_properties_location = os.path.join(hadoop_conf_dir, "task-log4j.properties")
 
@@ -127,8 +142,6 @@ ttnode_heapsize = "1024m"
 
 dtnode_heapsize = config['configurations']['hadoop-env']['dtnode_heapsize']
 mapred_pid_dir_prefix = default("/configurations/mapred-env/mapred_pid_dir_prefix","/var/run/hadoop-mapreduce")
-mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
-hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
 mapred_log_dir_prefix = default("/configurations/mapred-env/mapred_log_dir_prefix","/var/log/hadoop-mapreduce")
 
 #log4j.properties

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/flume.py

@@ -63,7 +63,7 @@ def flume(action = None):
       _set_desired_state('STARTED')
       
     flume_base = format('su -s /bin/bash {flume_user} -c "export JAVA_HOME={java_home}; '
-      '/usr/bin/flume-ng agent --name {{0}} --conf {{1}} --conf-file {{2}} {{3}}"')
+      '{flume_bin} agent --name {{0}} --conf {{1}} --conf-file {{2}} {{3}}"')
 
     for agent in cmd_target_names():
       flume_agent_conf_dir = params.flume_conf_dir + os.sep + agent

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/flume_check.py

@@ -31,7 +31,7 @@ class FlumeServiceCheck(Script):
       Execute(format("{kinit_path_local} -kt {http_keytab} {principal_replaced}"),
               user=params.smoke_user)
 
-    Execute(format('env JAVA_HOME={java_home} /usr/bin/flume-ng version'),
+    Execute(format('env JAVA_HOME={java_home} {flume_bin} version'),
             logoutput=True,
             tries = 3,
             try_sleep = 20)

+ 12 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/FLUME/package/scripts/params.py

@@ -26,9 +26,19 @@ proxyuser_group =  config['configurations']['hadoop-env']['proxyuser_group']
 
 security_enabled = False
 
-java_home = config['hostLevelParams']['java_home']
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  flume_conf_dir = format('/usr/hdp/{rpm_version}/etc/flume/conf')
+  flume_bin = format('/usr/hdp/{rpm_version}/flume/bin/flume-ng')
 
-flume_conf_dir = '/etc/flume/conf'
+else:
+  flume_conf_dir = '/etc/flume/conf'
+  flume_bin = '/usr/bin/flume-ng'
+
+java_home = config['hostLevelParams']['java_home']
 flume_log_dir = '/var/log/flume'
 flume_run_dir = '/var/run/flume'
 flume_user = 'flume'

+ 2 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/files/hbaseSmokeVerify.sh

@@ -21,7 +21,8 @@
 #
 conf_dir=$1
 data=$2
-echo "scan 'ambarismoketest'" | hbase --config $conf_dir shell > /tmp/hbase_chk_verify
+hbase_cmd=$3
+echo "scan 'ambarismoketest'" | $hbase_cmd --config $conf_dir shell > /tmp/hbase_chk_verify
 cat /tmp/hbase_chk_verify
 echo "Looking for $data"
 grep -q $data /tmp/hbase_chk_verify

+ 29 - 8
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/params.py

@@ -26,11 +26,32 @@ import status_params
 config = Script.get_config()
 exec_tmp_dir = Script.get_tmp_dir()
 
-hbase_conf_dir = "/etc/hbase/conf"
-daemon_script = "/usr/lib/hbase/bin/hbase-daemon.sh"
-region_mover = "/usr/lib/hbase/bin/region_mover.rb"
-region_drainer = "/usr/lib/hbase/bin/draining_servers.rb"
-hbase_cmd = "/usr/lib/hbase/bin/hbase"
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+#RPM versioning support
+  rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  hbase_conf_dir = format('/usr/hdp/{rpm_version}/etc/hbase/conf')
+  daemon_script = format('/usr/hdp/{rpm_version}/hbase/bin/hbase-daemon.sh')
+  region_mover = format('/usr/hdp/{rpm_version}/hbase/bin/region_mover.rb')
+  region_drainer = format('/usr/hdp/{rpm_version}hbase/bin/draining_servers.rb')
+  hbase_cmd = format('/usr/hdp/{rpm_version}/hbase/bin/hbase')
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_bin_dir = "/usr/bin"
+  hbase_conf_dir = "/etc/hbase/conf"
+  daemon_script = "/usr/lib/hbase/bin/hbase-daemon.sh"
+  region_mover = "/usr/lib/hbase/bin/region_mover.rb"
+  region_drainer = "/usr/lib/hbase/bin/draining_servers.rb"
+  hbase_cmd = "/usr/lib/hbase/bin/hbase"
+
 hbase_excluded_hosts = config['commandParams']['excluded_hosts']
 hbase_drain_only = config['commandParams']['mark_draining_only']
 hbase_included_hosts = config['commandParams']['included_hosts']
@@ -72,7 +93,7 @@ if 'slave_hosts' in config['clusterHostInfo']:
   rs_hosts = default('/clusterHostInfo/hbase_rs_hosts', '/clusterHostInfo/slave_hosts') #if hbase_rs_hosts not given it is assumed that region servers on same nodes as slaves
 else:
   rs_hosts = default('/clusterHostInfo/hbase_rs_hosts', '/clusterHostInfo/all_hosts') 
-  
+
 smoke_test_user = config['configurations']['cluster-env']['smokeuser']
 smokeuser_permissions = "RWXCA"
 service_check_data = functions.get_unique_id_and_date()
@@ -105,7 +126,6 @@ hbase_hdfs_root_dir = config['configurations']['hbase-site']['hbase.rootdir']
 hbase_staging_dir = "/apps/hbase/staging"
 #for create_hdfs_directory
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
@@ -119,5 +139,6 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )

+ 3 - 3
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/package/scripts/service_check.py

@@ -44,7 +44,7 @@ class HbaseServiceCheck(Script):
     
     if params.security_enabled:    
       hbase_grant_premissions_file = format("{exec_tmp_dir}/hbase_grant_permissions.sh")
-      grantprivelegecmd = format("{kinit_cmd} hbase shell {hbase_grant_premissions_file}")
+      grantprivelegecmd = format("{kinit_cmd} {hbase_cmd} shell {hbase_grant_premissions_file}")
   
       File( hbase_grant_premissions_file,
         owner   = params.hbase_user,
@@ -57,8 +57,8 @@ class HbaseServiceCheck(Script):
         user = params.hbase_user,
       )
 
-    servicecheckcmd = format("{smokeuser_kinit_cmd} hbase --config {hbase_conf_dir} shell {hbase_servicecheck_file}")
-    smokeverifycmd = format("{smokeuser_kinit_cmd} {exec_tmp_dir}/hbaseSmokeVerify.sh {hbase_conf_dir} {service_check_data}")
+    servicecheckcmd = format("{smokeuser_kinit_cmd} {hbase_cmd} --config {hbase_conf_dir} shell {hbase_servicecheck_file}")
+    smokeverifycmd = format("{smokeuser_kinit_cmd} {exec_tmp_dir}/hbaseSmokeVerify.sh {hbase_conf_dir} {service_check_data} {hbase_cmd}")
   
     Execute( servicecheckcmd,
       tries     = 3,

+ 3 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/files/checkForFormat.sh

@@ -24,6 +24,8 @@ export hdfs_user=$1
 shift
 export conf_dir=$1
 shift
+export bin_dir=$1
+shift
 export old_mark_dir=$1
 shift
 export mark_dir=$1
@@ -56,7 +58,7 @@ if [[ ! -d $mark_dir ]] ; then
   done
 
   if [[ $EXIT_CODE == 0 ]] ; then
-    su - ${hdfs_user} -c "yes Y | hadoop --config ${conf_dir} ${command}"
+    su - ${hdfs_user} -c "export PATH=$PATH:${bin_dir} ; yes Y | hadoop --config ${conf_dir} ${command}"
   else
     echo "ERROR: Namenode directory(s) is non empty. Will not format the namenode. List of non-empty namenode dirs ${list_of_non_empty_dirs}"
   fi

+ 9 - 6
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/hdfs_namenode.py

@@ -45,11 +45,11 @@ def namenode(action=None, do_format=True):
       create_log_dir=True
     )
     if params.dfs_ha_enabled:
-      dfs_check_nn_status_cmd = format("su - {hdfs_user} -c 'hdfs haadmin -getServiceState {namenode_id} | grep active > /dev/null'")
+      dfs_check_nn_status_cmd = format("su - {hdfs_user} -c 'export PATH=$PATH:{hadoop_bin_dir} ; hdfs --config {hadoop_conf_dir} haadmin -getServiceState {namenode_id} | grep active > /dev/null'")
     else:
       dfs_check_nn_status_cmd = None
 
-    namenode_safe_mode_off = format("su - {hdfs_user} -c 'hadoop dfsadmin -safemode get' | grep 'Safe mode is OFF'")
+    namenode_safe_mode_off = format("su - {hdfs_user} -c 'export PATH=$PATH:{hadoop_bin_dir} ; hadoop --config {hadoop_conf_dir} dfsadmin -safemode get' | grep 'Safe mode is OFF'")
 
     if params.security_enabled:
       Execute(format("{kinit_path_local} -kt {hdfs_user_keytab} {hdfs_principal_name}"),
@@ -110,14 +110,16 @@ def format_namenode(force=None):
   if not params.dfs_ha_enabled:
     if force:
       ExecuteHadoop('namenode -format',
-                    kinit_override=True)
+                    kinit_override=True,
+                    bin_dir=params.hadoop_bin_dir,
+                    conf_dir=hadoop_conf_dir)
     else:
       File(format("{tmp_dir}/checkForFormat.sh"),
            content=StaticFile("checkForFormat.sh"),
            mode=0755)
       Execute(format(
-        "{tmp_dir}/checkForFormat.sh {hdfs_user} {hadoop_conf_dir} {old_mark_dir} "
-        "{mark_dir} {dfs_name_dir}"),
+        "{tmp_dir}/checkForFormat.sh {hdfs_user} {hadoop_conf_dir} "
+        "{hadoop_bin_dir} {old_mark_dir} {mark_dir} {dfs_name_dir}"),
               not_if=format("test -d {old_mark_dir} || test -d {mark_dir}"),
               path="/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin"
       )
@@ -154,4 +156,5 @@ def decommission():
   ExecuteHadoop(nn_refresh_cmd,
                 user=hdfs_user,
                 conf_dir=conf_dir,
-                kinit_override=True)
+                kinit_override=True,
+                bin_dir=params.hadoop_bin_dir)

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/namenode.py

@@ -88,7 +88,7 @@ class NameNode(Script):
     
     
     def startRebalancingProcess(threshold):
-      rebalanceCommand = format('hadoop --config {hadoop_conf_dir} balancer -threshold {threshold}')
+      rebalanceCommand = format('export PATH=$PATH:{hadoop_bin_dir} ; hadoop --config {hadoop_conf_dir} balancer -threshold {threshold}')
       return ['su','-',params.hdfs_user,'-c', rebalanceCommand]
     
     command = startRebalancingProcess(threshold)

+ 24 - 10
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/params.py

@@ -24,6 +24,28 @@ import os
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_conf_empty_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf.empty")
+  mapreduce_libs_path = format("/usr/hdp/{rpm_version}/hadoop-mapreduce/*")
+  hadoop_libexec_dir = format("/usr/hdp/{rpm_version}/hadoop/libexec")
+  hadoop_bin = format("/usr/hdp/{rpm_version}/hadoop/sbin")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  limits_conf_dir = format("/usr/hdp/{rpm_version}/etc/security/limits.d")
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_conf_empty_dir = "/etc/hadoop/conf.empty"
+  mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
+  hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
+  hadoop_bin = "/usr/lib/hadoop/sbin"
+  hadoop_bin_dir = "/usr/bin"
+  limits_conf_dir = "/etc/security/limits.d"
+
+execute_path = os.environ['PATH'] + os.pathsep + hadoop_bin_dir
 ulimit_cmd = "ulimit -c unlimited; "
 
 #security params
@@ -100,9 +122,7 @@ proxyuser_group =  config['configurations']['hadoop-env']['proxyuser_group']
 nagios_group = config['configurations']['nagios-env']['nagios_group']
 
 #hadoop params
-hadoop_conf_dir = "/etc/hadoop/conf"
 hadoop_pid_dir_prefix = status_params.hadoop_pid_dir_prefix
-hadoop_bin = "/usr/lib/hadoop/sbin"
 
 hdfs_log_dir_prefix = config['configurations']['hadoop-env']['hdfs_log_dir_prefix']
 hadoop_root_logger = config['configurations']['hadoop-env']['hadoop_root_logger']
@@ -110,8 +130,6 @@ hadoop_root_logger = config['configurations']['hadoop-env']['hadoop_root_logger'
 dfs_domain_socket_path = config['configurations']['hdfs-site']['dfs.domain.socket.path']
 dfs_domain_socket_dir = os.path.dirname(dfs_domain_socket_path)
 
-hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
-
 jn_edits_dir = config['configurations']['hdfs-site']['dfs.journalnode.edits.dir']
 
 dfs_name_dir = config['configurations']['hdfs-site']['dfs.namenode.name.dir']
@@ -171,11 +189,10 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )
 
-limits_conf_dir = "/etc/security/limits.d"
-
 io_compression_codecs = config['configurations']['core-site']['io.compression.codecs']
 if not "com.hadoop.compression.lzo" in io_compression_codecs:
   exclude_packages = ["lzo", "hadoop-lzo", "hadoop-lzo-native", "liblzo2-2"]
@@ -184,8 +201,6 @@ else:
 name_node_params = default("/commandParams/namenode", None)
 
 #hadoop params
-hadoop_conf_empty_dir = "/etc/hadoop/conf.empty"
-
 hadoop_env_sh_template = config['configurations']['hadoop-env']['content']
 
 #hadoop-env.sh
@@ -209,5 +224,4 @@ ttnode_heapsize = "1024m"
 
 dtnode_heapsize = config['configurations']['hadoop-env']['dtnode_heapsize']
 mapred_pid_dir_prefix = default("/configurations/mapred-env/mapred_pid_dir_prefix","/var/run/hadoop-mapreduce")
-mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
 mapred_log_dir_prefix = default("/configurations/mapred-env/mapred_log_dir_prefix","/var/log/hadoop-mapreduce")

+ 20 - 7
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/package/scripts/service_check.py

@@ -31,13 +31,14 @@ class HdfsServiceCheck(Script):
 
     safemode_command = "dfsadmin -safemode get | grep OFF"
 
-    create_dir_cmd = format("fs -mkdir {dir} ; hadoop fs -chmod 777 {dir}")
-    test_dir_exists = format("hadoop fs -test -e {dir}")
+    create_dir_cmd = format("fs -mkdir {dir}")
+    chmod_command = format("fs -chmod 777 {dir}")
+    test_dir_exists = format("hadoop --config {hadoop_conf_dir} fs -test -e {dir}")
     cleanup_cmd = format("fs -rm {tmp_file}")
     #cleanup put below to handle retries; if retrying there wil be a stale file
     #that needs cleanup; exit code is fn of second command
     create_file_cmd = format(
-      "{cleanup_cmd}; hadoop fs -put /etc/passwd {tmp_file}")
+      "{cleanup_cmd}; hadoop --config {hadoop_conf_dir} fs -put /etc/passwd {tmp_file}")
     test_cmd = format("fs -test -e {tmp_file}")
     if params.security_enabled:
       Execute(format(
@@ -48,7 +49,8 @@ class HdfsServiceCheck(Script):
                   logoutput=True,
                   conf_dir=params.hadoop_conf_dir,
                   try_sleep=3,
-                  tries=20
+                  tries=20,
+                  bin_dir=params.hadoop_bin_dir
     )
     ExecuteHadoop(create_dir_cmd,
                   user=params.smoke_user,
@@ -56,21 +58,32 @@ class HdfsServiceCheck(Script):
                   not_if=test_dir_exists,
                   conf_dir=params.hadoop_conf_dir,
                   try_sleep=3,
-                  tries=5
+                  tries=5,
+                  bin_dir=params.hadoop_bin_dir
+    )
+    ExecuteHadoop(chmod_command,
+                  user=params.smoke_user,
+                  logoutput=True,
+                  conf_dir=params.hadoop_conf_dir,
+                  try_sleep=3,
+                  tries=5,
+                  bin_dir=params.hadoop_bin_dir
     )
     ExecuteHadoop(create_file_cmd,
                   user=params.smoke_user,
                   logoutput=True,
                   conf_dir=params.hadoop_conf_dir,
                   try_sleep=3,
-                  tries=5
+                  tries=5,
+                  bin_dir=params.hadoop_bin_dir
     )
     ExecuteHadoop(test_cmd,
                   user=params.smoke_user,
                   logoutput=True,
                   conf_dir=params.hadoop_conf_dir,
                   try_sleep=3,
-                  tries=5
+                  tries=5,
+                  bin_dir=params.hadoop_bin_dir
     )
     if params.has_journalnode_hosts:
       journalnode_port = params.journalnode_port

+ 6 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hcat.py

@@ -25,6 +25,12 @@ import sys
 def hcat():
   import params
 
+  Directory(params.hive_conf_dir,
+            owner=params.hcat_user,
+            group=params.user_group,
+  )
+
+
   Directory(params.hcat_conf_dir,
             owner=params.hcat_user,
             group=params.user_group,

+ 6 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hcat_service_check.py

@@ -45,6 +45,7 @@ def hcat_service_check():
             user=params.smokeuser,
             try_sleep=5,
             path=['/usr/sbin', '/usr/local/nin', '/bin', '/usr/bin'],
+            environment = {'PATH' : params.execute_path},
             logoutput=True)
 
     if params.security_enabled:
@@ -55,7 +56,8 @@ def hcat_service_check():
                     security_enabled=params.security_enabled,
                     kinit_path_local=params.kinit_path_local,
                     keytab=params.hdfs_user_keytab,
-                    principal=params.hdfs_principal_name
+                    principal=params.hdfs_principal_name,
+                    bin_dir=params.hive_bin
       )
     else:
       ExecuteHadoop(test_cmd,
@@ -64,7 +66,8 @@ def hcat_service_check():
                     conf_dir=params.hadoop_conf_dir,
                     security_enabled=params.security_enabled,
                     kinit_path_local=params.kinit_path_local,
-                    keytab=params.hdfs_user_keytab
+                    keytab=params.hdfs_user_keytab,
+                    bin_dir=params.hive_bin
       )
 
     cleanup_cmd = format("{kinit_cmd} {tmp_dir}/hcatSmoke.sh hcatsmoke{unique} cleanup")
@@ -72,6 +75,7 @@ def hcat_service_check():
     Execute(cleanup_cmd,
             tries=3,
             user=params.smokeuser,
+            environment = {'PATH' : params.execute_path },
             try_sleep=5,
             path=['/usr/sbin', '/usr/local/nin', '/bin', '/usr/bin'],
             logoutput=True

+ 2 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive.py

@@ -188,6 +188,7 @@ def jdbc_connector():
     Execute(cmd,
             not_if=format("test -f {target}"),
             creates=params.target,
+            environment= {'PATH' : params.execute_path },
             path=["/bin", "/usr/bin/"])
   elif params.hive_jdbc_driver == "org.postgresql.Driver":
     cmd = format("hive mkdir -p {artifact_dir} ; cp /usr/share/java/{jdbc_jar_name} {target}")
@@ -195,6 +196,7 @@ def jdbc_connector():
     Execute(cmd,
             not_if=format("test -f {target}"),
             creates=params.target,
+            environment= {'PATH' : params.execute_path },
             path=["/bin", "usr/bin/"])
 
   elif params.hive_jdbc_driver == "oracle.jdbc.driver.OracleDriver":

+ 6 - 3
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/hive_service.py

@@ -49,6 +49,7 @@ def hive_service(
     
     Execute(demon_cmd,
             user=params.hive_user,
+            environment= {'PATH' : params.execute_path, 'HADOOP_HOME' : params.hadoop_home },
             not_if=process_id_exists
     )
 
@@ -103,8 +104,10 @@ def hive_service(
 def check_fs_root():
   import params  
   fs_root_url = format("{fs_root}{hive_apps_whs_dir}")
-  cmd = "/usr/lib/hive/bin/metatool -listFSRoot 2>/dev/null | grep hdfs://"
+  cmd = format("metatool -listFSRoot 2>/dev/null | grep hdfs://")
   code, out = call(cmd, user=params.hive_user)
   if code == 0 and fs_root_url.strip() != out.strip():
-    cmd = format("/usr/lib/hive/bin/metatool -updateLocation {fs_root}{hive_apps_whs_dir} {out}")
-    Execute(cmd, user=params.hive_user)
+    cmd = format("metatool -updateLocation {fs_root}{hive_apps_whs_dir} {out}")
+    Execute(cmd,
+            environment= {'PATH' : params.execute_path },
+            user=params.hive_user)

+ 4 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/install_jars.py

@@ -69,7 +69,8 @@ def install_tez_jars():
                     owner=params.tez_user,
                     dest_dir=app_dir_path,
                     kinnit_if_needed=kinit_if_needed,
-                    hdfs_user=params.hdfs_user
+                    hdfs_user=params.hdfs_user,
+                    hadoop_conf_dir=params.hadoop_conf_dir
       )
     pass
 
@@ -79,7 +80,8 @@ def install_tez_jars():
                     owner=params.tez_user,
                     dest_dir=lib_dir_path,
                     kinnit_if_needed=kinit_if_needed,
-                    hdfs_user=params.hdfs_user
+                    hdfs_user=params.hdfs_user,
+                    hadoop_conf_dir=params.hadoop_conf_dir
       )
     pass
 

+ 49 - 24
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/scripts/params.py

@@ -26,6 +26,53 @@ import os
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+hdp_stack_version = config['hostLevelParams']['stack_version']
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  hadoop_home = format('/usr/hdp/{rpm_version}/hadoop')
+  hive_conf_dir = format('/usr/hdp/{rpm_version}/etc/hive/conf')
+  hive_client_conf_dir = format('/usr/hdp/{rpm_version}/etc/hive/conf')
+  hive_server_conf_dir = format('/usr/hdp/{rpm_version}/etc/hive/conf.server')
+  hive_bin = format('/usr/hdp/{rpm_version}/hive/bin')
+  hive_lib = format('/usr/hdp/{rpm_version}/hive/lib')
+  tez_local_api_jars = format('/usr/hdp/{rpm_version}/tez/tez*.jar')
+  tez_local_lib_jars = format('/usr/hdp/{rpm_version}/tez/lib/*.jar')
+
+  if str(hdp_stack_version).startswith('2.0'):
+    hcat_conf_dir = format('/usr/hdp/{rpm_version}/etc/hcatalog/conf')
+    hcat_lib = format('/usr/hdp/{rpm_version}/hive/hcatalog/share/hcatalog')
+  # for newer versions
+  else:
+    hcat_conf_dir = format('/usr/hdp/{rpm_version}/etc/hive-hcatalog/conf')
+    hcat_lib = format('/usr/hdp/{rpm_version}/hive/hive-hcatalog/share/hcatalog')
+
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_bin_dir = "/usr/bin"
+  hadoop_home = '/usr'
+  hive_conf_dir = "/etc/hive/conf"
+  hive_bin = '/usr/lib/hive/bin'
+  hive_lib = '/usr/lib/hive/lib/'
+  hive_client_conf_dir = "/etc/hive/conf"
+  hive_server_conf_dir = '/etc/hive/conf.server'
+  tez_local_api_jars = '/usr/lib/tez/tez*.jar'
+  tez_local_lib_jars = '/usr/lib/tez/lib/*.jar'
+
+  if str(hdp_stack_version).startswith('2.0'):
+    hcat_conf_dir = '/etc/hcatalog/conf'
+    hcat_lib = '/usr/lib/hcatalog/share/hcatalog'
+  # for newer versions
+  else:
+    hcat_conf_dir = '/etc/hive-hcatalog/conf'
+    hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
+
+execute_path = os.environ['PATH'] + os.pathsep + hive_bin
 hive_metastore_user_name = config['configurations']['hive-site']['javax.jdo.option.ConnectionUserName']
 hive_jdbc_connection_url = config['configurations']['hive-site']['javax.jdo.option.ConnectionURL']
 
@@ -34,7 +81,6 @@ hive_metastore_db_type = config['configurations']['hive-env']['hive_database_typ
 
 #users
 hive_user = config['configurations']['hive-env']['hive_user']
-hive_lib = '/usr/lib/hive/lib/'
 #JDBC driver jar name
 hive_jdbc_driver = config['configurations']['hive-site']['javax.jdo.option.ConnectionDriverName']
 if hive_jdbc_driver == "com.mysql.jdbc.Driver":
@@ -51,11 +97,9 @@ check_db_connection_jar_name = "DBConnectionVerification.jar"
 check_db_connection_jar = format("/usr/lib/ambari-agent/{check_db_connection_jar_name}")
 
 #common
-hdp_stack_version = config['hostLevelParams']['stack_version']
 hive_metastore_port = get_port_from_url(config['configurations']['hive-site']['hive.metastore.uris']) #"9083"
 hive_var_lib = '/var/lib/hive'
 ambari_server_hostname = config['clusterHostInfo']['ambari_server_host'][0]
-hive_bin = '/usr/lib/hive/bin'
 hive_server_host = config['clusterHostInfo']['hive_server_host'][0]
 hive_server_port = default('/configurations/hive-site/hive.server2.thrift.port',"10000")
 hive_url = format("jdbc:hive2://{hive_server_host}:{hive_server_port}")
@@ -77,8 +121,6 @@ hive_log_dir = config['configurations']['hive-env']['hive_log_dir']
 hive_pid_dir = status_params.hive_pid_dir
 hive_pid = status_params.hive_pid
 #Default conf dir for client
-hive_client_conf_dir = "/etc/hive/conf"
-hive_server_conf_dir = "/etc/hive/conf.server"
 hive_conf_dirs_list = [hive_server_conf_dir, hive_client_conf_dir]
 
 if 'role' in config and config['role'] in ["HIVE_SERVER", "HIVE_METASTORE"]:
@@ -92,8 +134,6 @@ hive_database_name = config['configurations']['hive-env']['hive_database_name']
 #Starting hiveserver2
 start_hiveserver2_script = 'startHiveserver2.sh.j2'
 
-hadoop_home = '/usr'
-
 ##Starting metastore
 start_metastore_script = 'startMetastore.sh'
 hive_metastore_pid = status_params.hive_metastore_pid
@@ -133,15 +173,6 @@ else:
 
 ########## HCAT
 
-if str(hdp_stack_version).startswith('2.0'):
-  hcat_conf_dir = '/etc/hcatalog/conf'
-  hcat_lib = '/usr/lib/hcatalog/share/hcatalog'
-# for newer versions
-else:
-  hcat_conf_dir = '/etc/hive-hcatalog/conf'
-  hcat_lib = '/usr/lib/hive-hcatalog/share/hcatalog'
-
-
 hcat_dbroot = hcat_lib
 
 hcat_user = config['configurations']['hive-env']['hcat_user']
@@ -150,8 +181,6 @@ webhcat_user = config['configurations']['hive-env']['webhcat_user']
 hcat_pid_dir = status_params.hcat_pid_dir
 hcat_log_dir = config['configurations']['hive-env']['hcat_log_dir']
 
-hadoop_conf_dir = '/etc/hadoop/conf'
-
 #hive-log4j.properties.template
 if (('hive-log4j' in config['configurations']) and ('content' in config['configurations']['hive-log4j'])):
   log4j_props = config['configurations']['hive-log4j']['content']
@@ -172,7 +201,6 @@ hive_hdfs_user_mode = 0700
 hive_apps_whs_dir = config['configurations']['hive-site']["hive.metastore.warehouse.dir"]
 #for create_hdfs_directory
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
@@ -180,8 +208,6 @@ kinit_path_local = functions.get_kinit_path(["/usr/bin", "/usr/kerberos/bin", "/
 
 # Tez libraries
 tez_lib_uris = default("/configurations/tez-site/tez.lib.uris", None)
-tez_local_api_jars = '/usr/lib/tez/tez*.jar'
-tez_local_lib_jars = '/usr/lib/tez/lib/*.jar'
 tez_user = config['configurations']['tez-env']['tez_user']
 
 if System.get_instance().os_family == "ubuntu":
@@ -205,13 +231,12 @@ else:
 import functools
 #create partial functions with common arguments for every HdfsDirectory call
 #to create hdfs directory we need to call params.HdfsDirectory in code
-#create partial functions with common arguments for every HdfsDirectory call
-#to create hdfs directory we need to call params.HdfsDirectory in code
 HdfsDirectory = functools.partial(
   HdfsDirectory,
   conf_dir=hadoop_conf_dir,
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HIVE/package/templates/startHiveserver2.sh.j2

@@ -25,5 +25,5 @@ HIVE_SERVER2_OPTS=" -hiveconf hive.log.file=hiveserver2.log -hiveconf hive.log.d
 HIVE_SERVER2_OPTS="${HIVE_SERVER2_OPTS} -hiveconf hive.security.authenticator.manager=org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator -hiveconf hive.security.authorization.manager=org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory "
 {% endif %}
 
-HIVE_CONF_DIR=$4 /usr/lib/hive/bin/hiveserver2 -hiveconf hive.metastore.uris=" " ${HIVE_SERVER2_OPTS} > $1 2> $2 &
+HIVE_CONF_DIR=$4 {{hive_bin}}/hiveserver2 -hiveconf hive.metastore.uris=" " ${HIVE_SERVER2_OPTS} > $1 2> $2 &
 echo $!|cat>$3

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/configuration/oozie-env.xml

@@ -122,7 +122,7 @@ export OOZIE_ADMIN_PORT={{oozie_server_admin_port}}
 # The base URL for callback URLs to Oozie
 #
 # export OOZIE_BASE_URL="http://${OOZIE_HTTP_HOSTNAME}:${OOZIE_HTTP_PORT}/oozie"
-export JAVA_LIBRARY_PATH=/usr/lib/hadoop/lib/native/Linux-amd64-64
+export JAVA_LIBRARY_PATH={{hadoop_lib_home}}/native/Linux-amd64-64
     </value>
   </property>
 

+ 4 - 4
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/files/oozieSmoke2.sh

@@ -93,10 +93,10 @@ else
   kinitcmd=""
 fi
 
-su - ${smoke_test_user} -c "hdfs dfs -rm -r examples"
-su - ${smoke_test_user} -c "hdfs dfs -rm -r input-data"
-su - ${smoke_test_user} -c "hdfs dfs -copyFromLocal $OOZIE_EXAMPLES_DIR/examples examples"
-su - ${smoke_test_user} -c "hdfs dfs -copyFromLocal $OOZIE_EXAMPLES_DIR/examples/input-data input-data"
+su - ${smoke_test_user} -c "hdfs --config ${hadoop_conf_dir} dfs -rm -r examples"
+su - ${smoke_test_user} -c "hdfs --config ${hadoop_conf_dir} dfs -rm -r input-data"
+su - ${smoke_test_user} -c "hdfs --config ${hadoop_conf_dir} dfs -copyFromLocal $OOZIE_EXAMPLES_DIR/examples examples"
+su - ${smoke_test_user} -c "hdfs --config ${hadoop_conf_dir} dfs -copyFromLocal $OOZIE_EXAMPLES_DIR/examples/input-data input-data"
 
 cmd="${kinitcmd}source ${oozie_conf_dir}/oozie-env.sh ; /usr/bin/oozie -Doozie.auth.token.cache=false job -oozie $OOZIE_SERVER -config $OOZIE_EXAMPLES_DIR/examples/apps/map-reduce/job.properties  -run"
 echo $cmd

+ 2 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/scripts/oozie_service.py

@@ -37,7 +37,7 @@ def oozie_service(action = 'start'): # 'start' or 'stop'
       db_connection_check_command = None
       
     cmd1 =  format("cd {oozie_tmp_dir} && /usr/lib/oozie/bin/ooziedb.sh create -sqlfile oozie.sql -run")
-    cmd2 =  format("{kinit_if_needed} {put_shared_lib_to_hdfs_cmd} ; hadoop dfs -chmod -R 755 {oozie_hdfs_user_dir}/share")
+    cmd2 =  format("{kinit_if_needed} {put_shared_lib_to_hdfs_cmd} ; hadoop --config {hadoop_conf_dir} dfs -chmod -R 755 {oozie_hdfs_user_dir}/share")
 
     if not os.path.isfile(params.jdbc_driver_jar) and params.jdbc_driver_name == "org.postgresql.Driver":
       print "ERROR: jdbc file " + params.jdbc_driver_jar + " is unavailable. Please, follow next steps:\n" \
@@ -58,7 +58,7 @@ def oozie_service(action = 'start'): # 'start' or 'stop'
     
     Execute( cmd2,
       user = params.oozie_user,       
-      not_if = format("{kinit_if_needed} hadoop dfs -ls /user/oozie/share | awk 'BEGIN {{count=0;}} /share/ {{count++}} END {{if (count > 0) {{exit 0}} else {{exit 1}}}}'")
+      not_if = format("{kinit_if_needed} hadoop --config {hadoop_conf_dir} dfs -ls /user/oozie/share | awk 'BEGIN {{count=0;}} /share/ {{count++}} END {{if (count > 0) {{exit 0}} else {{exit 1}}}}'")
     )
     
     Execute( start_cmd,

+ 18 - 6
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/OOZIE/package/scripts/params.py

@@ -25,15 +25,28 @@ import status_params
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  hadoop_lib_home = format("/usr/hdp/{rpm_version}/hadoop/lib")
+  mapreduce_libs_path = format("/usr/hdp/{rpm_version}/hadoop-mapreduce/*")
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_bin_dir = "/usr/bin"
+  hadoop_lib_home = "/usr/lib/hadoop/lib"
+  mapreduce_libs_path = "/usr/lib/hadoop-mapreduce/*"
+
 oozie_user = config['configurations']['oozie-env']['oozie_user']
 smokeuser = config['configurations']['cluster-env']['smokeuser']
 conf_dir = "/etc/oozie/conf"
-hadoop_conf_dir = "/etc/hadoop/conf"
 user_group = config['configurations']['cluster-env']['user_group']
 jdk_location = config['hostLevelParams']['jdk_location']
 check_db_connection_jar_name = "DBConnectionVerification.jar"
 check_db_connection_jar = format("/usr/lib/ambari-agent/{check_db_connection_jar_name}")
-hadoop_prefix = "/usr"
 oozie_tmp_dir = "/var/tmp/oozie"
 oozie_hdfs_user_dir = format("/user/{oozie_user}")
 oozie_pid_dir = status_params.oozie_pid_dir
@@ -53,7 +66,6 @@ oozie_keytab = config['configurations']['oozie-env']['oozie_keytab']
 oozie_env_sh_template = config['configurations']['oozie-env']['content']
 
 oracle_driver_jar_name = "ojdbc6.jar"
-java_share_dir = "/usr/share/java"
 
 java_home = config['hostLevelParams']['java_home']
 oozie_metastore_user_name = config['configurations']['oozie-site']['oozie.service.JPAService.jdbc.username']
@@ -71,7 +83,7 @@ oozie_shared_lib = "/usr/lib/oozie/share"
 fs_root = config['configurations']['core-site']['fs.defaultFS']
 
 if str(hdp_stack_version).startswith('2.0') or str(hdp_stack_version).startswith('2.1'):
-  put_shared_lib_to_hdfs_cmd = format("hadoop dfs -put {oozie_shared_lib} {oozie_hdfs_user_dir}")
+  put_shared_lib_to_hdfs_cmd = format("hadoop --config {hadoop_conf_dir} dfs -put {oozie_shared_lib} {oozie_hdfs_user_dir}")
 # for newer
 else:
   put_shared_lib_to_hdfs_cmd = format("{oozie_setup_sh} sharelib create -fs {fs_root} -locallib {oozie_shared_lib}")
@@ -103,7 +115,6 @@ oozie_hdfs_user_dir = format("/user/{oozie_user}")
 oozie_hdfs_user_mode = 0775
 #for create_hdfs_directory
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
@@ -117,5 +128,6 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )

+ 17 - 3
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/package/scripts/params.py

@@ -25,8 +25,23 @@ from resource_management import *
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
-pig_conf_dir = "/etc/pig/conf"
-hadoop_conf_dir = "/etc/hadoop/conf"
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  hadoop_home = format('/usr/hdp/{rpm_version}/hadoop')
+  pig_conf_dir = format('/usr/hdp/{rpm_version}/etc/pig/conf')
+  pig_bin_dir = format('/usr/hdp/{rpm_version}/pig/bin')
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_bin_dir = "/usr/bin"
+  hadoop_home = '/usr'
+  pig_conf_dir = "/etc/pig/conf"
+  pig_bin_dir = ""
+
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
 smokeuser = config['configurations']['cluster-env']['smokeuser']
@@ -38,7 +53,6 @@ pig_env_sh_template = config['configurations']['pig-env']['content']
 
 # not supporting 32 bit jdk.
 java64_home = config['hostLevelParams']['java_home']
-hadoop_home = "/usr"
 
 pig_properties = config['configurations']['pig-properties']['content']
 

+ 6 - 4
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/PIG/package/scripts/service_check.py

@@ -31,7 +31,7 @@ class PigServiceCheck(Script):
 
     cleanup_cmd = format("dfs -rmr {output_file} {input_file}")
     #cleanup put below to handle retries; if retrying there wil be a stale file that needs cleanup; exit code is fn of second command
-    create_file_cmd = format("{cleanup_cmd}; hadoop dfs -put /etc/passwd {input_file} ") #TODO: inconsistent that second command needs hadoop
+    create_file_cmd = format("{cleanup_cmd}; hadoop --config {hadoop_conf_dir} dfs -put /etc/passwd {input_file} ") #TODO: inconsistent that second command needs hadoop
     test_cmd = format("fs -test -e {output_file}")
 
     ExecuteHadoop( create_file_cmd,
@@ -42,7 +42,8 @@ class PigServiceCheck(Script):
       # for kinit run
       keytab = params.smoke_user_keytab,
       security_enabled = params.security_enabled,
-      kinit_path_local = params.kinit_path_local
+      kinit_path_local = params.kinit_path_local,
+      bin_dir = params.hadoop_bin_dir
     )
 
     File( format("{tmp_dir}/pigSmoke.sh"),
@@ -53,13 +54,14 @@ class PigServiceCheck(Script):
     Execute( format("pig {tmp_dir}/pigSmoke.sh"),
       tries     = 3,
       try_sleep = 5,
-      path      = '/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
+      path      = format('{pig_bin_dir}:/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin'),
       user      = params.smokeuser
     )
 
     ExecuteHadoop( test_cmd,
       user      = params.smokeuser,
-      conf_dir = params.hadoop_conf_dir
+      conf_dir = params.hadoop_conf_dir,
+      bin_dir = params.hadoop_bin_dir
     )
 
 if __name__ == "__main__":

+ 9 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/SQOOP/package/scripts/params.py

@@ -21,6 +21,15 @@ from resource_management import *
 
 config = Script.get_config()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  zoo_conf_dir = format('/usr/hdp/{rpm_version}/etc/zookeeper')
+else:
+  zoo_conf_dir = "/etc/zookeeper"
+
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 smokeuser = config['configurations']['cluster-env']['smokeuser']
 user_group = config['configurations']['cluster-env']['user_group']
@@ -29,7 +38,6 @@ sqoop_env_sh_template = config['configurations']['sqoop-env']['content']
 sqoop_conf_dir = "/usr/lib/sqoop/conf"
 hbase_home = "/usr"
 hive_home = "/usr"
-zoo_conf_dir = "/etc/zookeeper"
 sqoop_lib = "/usr/lib/sqoop/lib"
 sqoop_user = config['configurations']['sqoop-env']['sqoop_user']
 

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/configuration/webhcat-env.xml

@@ -47,7 +47,7 @@ CONSOLE_LOG={{templeton_log_dir}}/webhcat-console.log
 #HCAT_PREFIX=hive_prefix
 
 # Set HADOOP_HOME to point to a specific hadoop install directory
-export HADOOP_HOME=/usr/lib/hadoop
+export HADOOP_HOME={{hadoop_home}}
     </value>
   </property>
   

+ 30 - 11
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/package/scripts/params.py

@@ -26,16 +26,36 @@ import status_params
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
-hcat_user = config['configurations']['hive-env']['hcat_user']
-webhcat_user = config['configurations']['hive-env']['webhcat_user']
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
 
-if str(config['hostLevelParams']['stack_version']).startswith('2.0'):
-  config_dir = '/etc/hcatalog/conf'
-  webhcat_bin_dir = '/usr/lib/hcatalog/sbin'
-# for newer versions
+#hadoop params
+hdp_stack_version = config['hostLevelParams']['stack_version']
+if rpm_version is not None:
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  hadoop_home = format('/usr/hdp/{rpm_version}/hadoop')
+  hadoop_streeming_jars = format("/usr/hdp/{rpm_version}/hadoop-mapreduce/hadoop-streaming-*.jar")
+  if str(hdp_stack_version).startswith('2.0'):
+    config_dir = format('/usr/hdp/{rpm_version}/etc/hcatalog/conf')
+    webhcat_bin_dir = format('/usr/hdp/{rpm_version}/hive/hcatalog/sbin')
+  # for newer versions
+  else:
+    config_dir = format('/usr/hdp/{rpm_version}/etc/hive-webhcat/conf')
+    webhcat_bin_dir = format('/usr/hdp/{rpm_version}/hive/hive-hcatalog/sbin')
 else:
-  config_dir = '/etc/hive-webhcat/conf'
-  webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
+  hadoop_bin_dir = "/usr/bin"
+  hadoop_home = '/usr'
+  hadoop_streeming_jars = '/usr/lib/hadoop-mapreduce/hadoop-streaming-*.jar'
+  if str(hdp_stack_version).startswith('2.0'):
+    config_dir = '/etc/hcatalog/conf'
+    webhcat_bin_dir = '/usr/lib/hcatalog/sbin'
+  # for newer versions
+  else:
+    config_dir = '/etc/hive-webhcat/conf'
+    webhcat_bin_dir = '/usr/lib/hive-hcatalog/sbin'
+
+hcat_user = config['configurations']['hive-env']['hcat_user']
+webhcat_user = config['configurations']['hive-env']['webhcat_user']
 
 webhcat_env_sh_template = config['configurations']['webhcat-env']['content']
 templeton_log_dir = config['configurations']['hive-env']['hcat_log_dir']
@@ -46,7 +66,6 @@ pid_file = status_params.pid_file
 hadoop_conf_dir = config['configurations']['webhcat-site']['templeton.hadoop.conf.dir']
 templeton_jar = config['configurations']['webhcat-site']['templeton.jar']
 
-hadoop_home = '/usr'
 user_group = config['configurations']['cluster-env']['user_group']
 
 webhcat_server_host = config['clusterHostInfo']['webhcat_server_host']
@@ -64,7 +83,6 @@ webhcat_hdfs_user_mode = 0755
 webhcat_apps_dir = "/apps/webhcat"
 #for create_hdfs_directory
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 security_param = "true" if security_enabled else "false"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
@@ -79,5 +97,6 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )

+ 7 - 4
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/WEBHCAT/package/scripts/webhcat.py

@@ -84,12 +84,13 @@ def webhcat():
             path='/bin'
     )
 
-  CopyFromLocal('/usr/lib/hadoop-mapreduce/hadoop-streaming-*.jar',
+  CopyFromLocal(params.hadoop_streeming_jars,
                 owner=params.webhcat_user,
                 mode=0755,
                 dest_dir=params.webhcat_apps_dir,
                 kinnit_if_needed=kinit_if_needed,
-                hdfs_user=params.hdfs_user
+                hdfs_user=params.hdfs_user,
+                hadoop_conf_dir=params.hadoop_conf_dir
   )
 
   CopyFromLocal('/usr/share/HDP-webhcat/pig.tar.gz',
@@ -97,7 +98,8 @@ def webhcat():
                 mode=0755,
                 dest_dir=params.webhcat_apps_dir,
                 kinnit_if_needed=kinit_if_needed,
-                hdfs_user=params.hdfs_user
+                hdfs_user=params.hdfs_user,
+                hadoop_conf_dir=params.hadoop_conf_dir
   )
 
   CopyFromLocal('/usr/share/HDP-webhcat/hive.tar.gz',
@@ -105,5 +107,6 @@ def webhcat():
                 mode=0755,
                 dest_dir=params.webhcat_apps_dir,
                 kinnit_if_needed=kinit_if_needed,
-                hdfs_user=params.hdfs_user
+                hdfs_user=params.hdfs_user,
+                hadoop_conf_dir=params.hadoop_conf_dir
   )

+ 31 - 14
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py

@@ -18,6 +18,7 @@ limitations under the License.
 Ambari Agent
 
 """
+import os
 
 from resource_management import *
 import status_params
@@ -26,7 +27,34 @@ import status_params
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
-config_dir = "/etc/hadoop/conf"
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_libexec_dir = format("/usr/hdp/{rpm_version}/hadoop/libexec")
+  hadoop_bin = format("/usr/hdp/{rpm_version}/hadoop/sbin")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+  limits_conf_dir = format("/usr/hdp/{rpm_version}/etc/security/limits.d")
+  hadoop_yarn_home = format('/usr/hdp/{rpm_version}/hadoop-yarn')
+  hadoop_mapred2_jar_location = format('/usr/hdp/{rpm_version}/hadoop-mapreduce')
+  mapred_bin = format('/usr/hdp/{rpm_version}/hadoop-mapreduce/sbin')
+  yarn_bin = format('/usr/hdp/{rpm_version}/hadoop-yarn/sbin')
+  yarn_container_bin = format('/usr/hdp/{rpm_version}/hadoop-yarn/bin')
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_libexec_dir = "/usr/lib/hadoop/libexec"
+  hadoop_bin = "/usr/lib/hadoop/sbin"
+  hadoop_bin_dir = "/usr/bin"
+  limits_conf_dir = "/etc/security/limits.d"
+  hadoop_yarn_home = '/usr/lib/hadoop-yarn'
+  hadoop_mapred2_jar_location = "/usr/lib/hadoop-mapreduce"
+  mapred_bin = "/usr/lib/hadoop-mapreduce/sbin"
+  yarn_bin = "/usr/lib/hadoop-yarn/sbin"
+  yarn_container_bin = "/usr/lib/hadoop-yarn/bin"
+
+execute_path = os.environ['PATH'] + os.pathsep + hadoop_bin_dir
 
 ulimit_cmd = "ulimit -c unlimited;"
 
@@ -49,8 +77,6 @@ rm_nodes_exclude_path = default("/configurations/yarn-site/yarn.resourcemanager.
 java64_home = config['hostLevelParams']['java_home']
 hadoop_ssl_enabled = default("/configurations/core-site/hadoop.ssl.enabled", False)
 
-hadoop_libexec_dir = '/usr/lib/hadoop/libexec'
-hadoop_yarn_home = '/usr/lib/hadoop-yarn'
 yarn_heapsize = config['configurations']['yarn-env']['yarn_heapsize']
 resourcemanager_heapsize = config['configurations']['yarn-env']['resourcemanager_heapsize']
 nodemanager_heapsize = config['configurations']['yarn-env']['nodemanager_heapsize']
@@ -77,8 +103,6 @@ hs_webui_address = config['configurations']['mapred-site']['mapreduce.jobhistory
 nm_local_dirs = config['configurations']['yarn-site']['yarn.nodemanager.local-dirs']
 nm_log_dirs = config['configurations']['yarn-site']['yarn.nodemanager.log-dirs']
 
-
-hadoop_mapred2_jar_location = "/usr/lib/hadoop-mapreduce"
 distrAppJarName = "hadoop-yarn-applications-distributedshell-2.*.jar"
 hadoopMapredExamplesJarName = "hadoop-mapreduce-examples-2.*.jar"
 
@@ -90,13 +114,7 @@ yarn_log_dir = format("{yarn_log_dir_prefix}/{yarn_user}")
 mapred_job_summary_log = format("{mapred_log_dir_prefix}/{mapred_user}/hadoop-mapreduce.jobsummary.log")
 yarn_job_summary_log = format("{yarn_log_dir_prefix}/{yarn_user}/hadoop-mapreduce.jobsummary.log")
 
-mapred_bin = "/usr/lib/hadoop-mapreduce/sbin"
-yarn_bin = "/usr/lib/hadoop-yarn/sbin"
-
 user_group = config['configurations']['cluster-env']['user_group']
-limits_conf_dir = "/etc/security/limits.d"
-hadoop_conf_dir = "/etc/hadoop/conf"
-yarn_container_bin = "/usr/lib/hadoop-yarn/bin"
 
 #exclude file
 exclude_hosts = default("/clusterHostInfo/decom_nm_hosts", [])
@@ -128,7 +146,6 @@ jobhistory_heapsize = default("/configurations/mapred-env/jobhistory_heapsize",
 
 #for create_hdfs_directory
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
@@ -142,11 +159,11 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )
 update_exclude_file_only = config['commandParams']['update_exclude_file_only']
 
-hadoop_bin = "/usr/lib/hadoop/sbin"
 mapred_tt_group = default("/configurations/mapred-site/mapreduce.tasktracker.group", user_group)
 
 #taskcontroller.cfg

+ 3 - 2
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/resourcemanager.py

@@ -78,10 +78,10 @@ class Resourcemanager(Script):
     env.set_params(params)
     rm_kinit_cmd = params.rm_kinit_cmd
     yarn_user = params.yarn_user
-    conf_dir = params.config_dir
+    conf_dir = params.hadoop_conf_dir
     user_group = params.user_group
 
-    yarn_refresh_cmd = format("{rm_kinit_cmd} /usr/bin/yarn --config {conf_dir} rmadmin -refreshNodes")
+    yarn_refresh_cmd = format("{rm_kinit_cmd} yarn --config {conf_dir} rmadmin -refreshNodes")
 
     File(params.exclude_file_path,
          content=Template("exclude_hosts_list.j2"),
@@ -91,6 +91,7 @@ class Resourcemanager(Script):
 
     if params.update_exclude_file_only == False:
       Execute(yarn_refresh_cmd,
+            environment= {'PATH' : params.execute_path },
             user=yarn_user)
       pass
     pass

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py

@@ -35,7 +35,7 @@ def service(componentName, action='start', serviceName='yarn'):
     pid_file = format("{yarn_pid_dir}/yarn-{yarn_user}-{componentName}.pid")
     usr = params.yarn_user
 
-  cmd = format("export HADOOP_LIBEXEC_DIR={hadoop_libexec_dir} && {daemon} --config {config_dir}")
+  cmd = format("export HADOOP_LIBEXEC_DIR={hadoop_libexec_dir} && {daemon} --config {hadoop_conf_dir}")
 
   if action == 'start':
     daemon_cmd = format("{ulimit_cmd} {cmd} start {componentName}")

+ 2 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service_check.py

@@ -27,7 +27,7 @@ class ServiceCheck(Script):
     import params
     env.set_params(params)
 
-    run_yarn_check_cmd = "/usr/bin/yarn node -list"
+    run_yarn_check_cmd = format("yarn --config {hadoop_conf_dir} node -list")
 
     component_type = 'rm'
     if params.hadoop_ssl_enabled:
@@ -60,6 +60,7 @@ class ServiceCheck(Script):
     )
 
     Execute(run_yarn_check_cmd,
+            environment= {'PATH' : params.execute_path },
             user=params.smokeuser
     )
 

+ 7 - 7
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/yarn.py

@@ -78,7 +78,7 @@ def yarn(name = None):
   )
 
   XmlConfig("core-site.xml",
-            conf_dir=params.config_dir,
+            conf_dir=params.hadoop_conf_dir,
             configurations=params.config['configurations']['core-site'],
             configuration_attributes=params.config['configuration_attributes']['core-site'],
             owner=params.hdfs_user,
@@ -87,7 +87,7 @@ def yarn(name = None):
   )
 
   XmlConfig("mapred-site.xml",
-            conf_dir=params.config_dir,
+            conf_dir=params.hadoop_conf_dir,
             configurations=params.config['configurations']['mapred-site'],
             configuration_attributes=params.config['configuration_attributes']['mapred-site'],
             owner=params.yarn_user,
@@ -96,7 +96,7 @@ def yarn(name = None):
   )
 
   XmlConfig("yarn-site.xml",
-            conf_dir=params.config_dir,
+            conf_dir=params.hadoop_conf_dir,
             configurations=params.config['configurations']['yarn-site'],
             configuration_attributes=params.config['configuration_attributes']['yarn-site'],
             owner=params.yarn_user,
@@ -105,7 +105,7 @@ def yarn(name = None):
   )
 
   XmlConfig("capacity-scheduler.xml",
-            conf_dir=params.config_dir,
+            conf_dir=params.hadoop_conf_dir,
             configurations=params.config['configurations']['capacity-scheduler'],
             configuration_attributes=params.config['configuration_attributes']['capacity-scheduler'],
             owner=params.yarn_user,
@@ -140,7 +140,7 @@ def yarn(name = None):
        content=Template('mapreduce.conf.j2')
   )
 
-  File(format("{config_dir}/yarn-env.sh"),
+  File(format("{hadoop_conf_dir}/yarn-env.sh"),
        owner=params.yarn_user,
        group=params.user_group,
        mode=0755,
@@ -154,7 +154,7 @@ def yarn(name = None):
          mode=06050
     )
 
-    File(format("{config_dir}/container-executor.cfg"),
+    File(format("{hadoop_conf_dir}/container-executor.cfg"),
          group=params.user_group,
          mode=0644,
          content=Template('container-executor.cfg.j2')
@@ -168,7 +168,7 @@ def yarn(name = None):
     tc_mode = None
     tc_owner = params.hdfs_user
 
-  File(format("{config_dir}/mapred-env.sh"),
+  File(format("{hadoop_conf_dir}/mapred-env.sh"),
        owner=tc_owner,
        content=InlineTemplate(params.mapred_env_sh_template)
   )

+ 13 - 4
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/ZOOKEEPER/package/scripts/params.py

@@ -26,15 +26,24 @@ import status_params
 config = Script.get_config()
 tmp_dir = Script.get_tmp_dir()
 
-config_dir = "/etc/zookeeper/conf"
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  config_dir = format('/usr/hdp/{rpm_version}/etc/zookeeper/conf')
+  zk_bin = format('/usr/hdp/{rpm_version}/zookeeper/bin')
+  smoke_script = format('/usr/hdp/{rpm_version}/zookeeper/bin/zkCli.sh')
+else:
+  config_dir = "/etc/zookeeper/conf"
+  zk_bin = '/usr/lib/zookeeper/bin'
+  smoke_script = "/usr/lib/zookeeper/bin/zkCli.sh"
+
 zk_user =  config['configurations']['zookeeper-env']['zk_user']
 hostname = config['hostname']
-zk_bin = '/usr/lib/zookeeper/bin'
 user_group = config['configurations']['cluster-env']['user_group']
 zk_env_sh_template = config['configurations']['zookeeper-env']['content']
 
-smoke_script = "/usr/lib/zookeeper/bin/zkCli.sh"
-
 zk_log_dir = config['configurations']['zookeeper-env']['zk_log_dir']
 zk_data_dir = config['configurations']['zookeeper-env']['zk_data_dir']
 zk_pid_dir = status_params.zk_pid_dir

+ 13 - 2
ambari-server/src/main/resources/stacks/HDP/2.1/services/FALCON/package/scripts/params.py

@@ -23,6 +23,17 @@ from status_params import *
 
 config = Script.get_config()
 
+#RPM versioning support
+rpm_version = default("/configurations/hadoop-env/rpm_version", None)
+
+#hadoop params
+if rpm_version is not None:
+  hadoop_conf_dir = format("/usr/hdp/{rpm_version}/etc/hadoop/conf")
+  hadoop_bin_dir = format("/usr/hdp/{rpm_version}/hadoop/bin")
+else:
+  hadoop_conf_dir = "/etc/hadoop/conf"
+  hadoop_bin_dir = "/usr/bin"
+
 oozie_user = config['configurations']['oozie-env']['oozie_user']
 falcon_user = config['configurations']['falcon-env']['falcon_user']
 smoke_user =  config['configurations']['cluster-env']['smokeuser']
@@ -53,7 +64,6 @@ flacon_apps_dir = '/apps/falcon'
 #for create_hdfs_directory
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 hostname = config["hostname"]
-hadoop_conf_dir = "/etc/hadoop/conf"
 hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab']
 hdfs_user = config['configurations']['hadoop-env']['hdfs_user']
 hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name']
@@ -67,5 +77,6 @@ HdfsDirectory = functools.partial(
   hdfs_user=hdfs_user,
   security_enabled = security_enabled,
   keytab = hdfs_user_keytab,
-  kinit_path_local = kinit_path_local
+  kinit_path_local = kinit_path_local,
+  bin_dir = hadoop_bin_dir
 )

+ 2 - 3
ambari-server/src/main/resources/stacks/HDP/2.1/services/STORM/package/scripts/params.py

@@ -37,8 +37,7 @@ nimbus_host = config['configurations']['storm-site']['nimbus.host']
 rest_api_port = "8745"
 rest_api_admin_port = "8746"
 rest_api_conf_file = format("{conf_dir}/config.yaml")
-rest_lib_dir = "/usr/lib/storm/contrib/storm-rest"
-java_home = config['hostLevelParams']['java_home']
+rest_lib_dir = default("/configurations/storm-env/rest_lib_dir","/usr/lib/storm/contrib/storm-rest")
 storm_env_sh_template = config['configurations']['storm-env']['content']
 
 if 'ganglia_server_host' in config['clusterHostInfo'] and \
@@ -48,7 +47,7 @@ if 'ganglia_server_host' in config['clusterHostInfo'] and \
   ganglia_report_interval = 60
 else:
   ganglia_installed = False
-  
+
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 
 if security_enabled:

+ 23 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/metainfo.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+    <versions>
+	  <active>true</active>
+    </versions>
+    <extends>2.1</extends>
+</metainfo>

+ 82 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/repos/repoinfo.xml

@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<reposinfo>
+  <os type="redhat6">
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.9.9.9-98</baseurl>
+      <repoid>HDP-2.9.9.9-98</repoid>
+      <reponame>HDP</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/updates/2.2.0.0</baseurl>
+      <repoid>HDP-2.2.0.0</repoid>
+      <reponame>HDP-2.2</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.17/repos/centos6</baseurl>
+      <repoid>HDP-UTILS-1.1.0.17</repoid>
+      <reponame>HDP-UTILS</reponame>
+    </repo>
+  </os>
+  <os type="redhat5">
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/BUILDS/2.9.9.9-98</baseurl>
+      <repoid>HDP-2.9.9.9-98</repoid>
+      <reponame>HDP</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos5/2.x/updates/2.2.0.0</baseurl>
+      <repoid>HDP-2.2.0.0</repoid>
+      <reponame>HDP-2.2</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.17/repos/centos5</baseurl>
+      <repoid>HDP-UTILS-1.1.0.17</repoid>
+      <reponame>HDP-UTILS</reponame>
+    </repo>
+  </os>
+  <os type="suse11">
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11/2.x/BUILDS/2.9.9.9-98</baseurl>
+      <repoid>HDP-2.9.9.9-98</repoid>
+      <reponame>HDP</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11/2.x/updates/2.2.0.0</baseurl>
+      <repoid>HDP-2.2.0.0</repoid>
+      <reponame>HDP-2.2</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.17/repos/suse11</baseurl>
+      <repoid>HDP-UTILS-1.1.0.17</repoid>
+      <reponame>HDP-UTILS</reponame>
+    </repo>
+  </os>
+  <os type="debian12">
+    <repo>
+      <baseurl>REPLACE_WITH_UBUNTU12_URL</baseurl>
+      <repoid>HDP-2.1</repoid>
+      <reponame>HDP</reponame>
+    </repo>
+    <repo>
+      <baseurl>http://dev.hortonworks.com.s3.amazonaws.com/HDP-UTILS-1.1.0.19/repos/ubuntu12</baseurl>
+      <repoid>HDP-UTILS-1.1.0.19</repoid>
+      <reponame>HDP-UTILS</reponame>
+    </repo>
+  </os>
+</reposinfo>

+ 88 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/role_command_order.json

@@ -0,0 +1,88 @@
+{
+  "_comment" : "Record format:",
+  "_comment" : "blockedRole-blockedCommand: [blockerRole1-blockerCommand1, blockerRole2-blockerCommand2, ...]",
+  "general_deps" : {
+    "_comment" : "dependencies for all cases",
+    "NAGIOS_SERVER-INSTALL" : ["HIVE_CLIENT-INSTALL", "HCAT-INSTALL",
+        "MAPREDUCE_CLIENT-INSTALL", "OOZIE_CLIENT-INSTALL"],
+    "NIMBUS-START" : ["ZOOKEEPER_SERVER-START", "NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "SUPERVISOR-START" : ["NIMBUS-START"],
+    "STORM_UI_SERVER-START" : ["NIMBUS-START"],
+    "DRPC_SERVER-START" : ["NIMBUS-START"],
+    "STORM_REST_API-START" : ["NIMBUS-START", "STORM_UI_SERVER-START", "SUPERVISOR-START", "DRPC_SERVER-START"],
+    "HBASE_MASTER-START": ["ZOOKEEPER_SERVER-START"],
+    "HBASE_REGIONSERVER-START": ["HBASE_MASTER-START"],
+    "OOZIE_SERVER-START": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "WEBHCAT_SERVER-START": ["NODEMANAGER-START", "HIVE_SERVER-START"],
+    "HIVE_METASTORE-START": ["MYSQL_SERVER-START"],
+    "HIVE_SERVER-START": ["NODEMANAGER-START", "MYSQL_SERVER-START"],
+    "HUE_SERVER-START": ["HIVE_SERVER-START", "HCAT-START", "OOZIE_SERVER-START"],
+    "FLUME_HANDLER-START": ["OOZIE_SERVER-START"],
+    "FALCON_SERVER-START": ["NAMENODE-START", "DATANODE-START", "OOZIE_SERVER-START"],
+    "NAGIOS_SERVER-START": ["HBASE_MASTER-START", "HBASE_REGIONSERVER-START",
+        "GANGLIA_SERVER-START", "GANGLIA_MONITOR-START", "HCAT-START",
+        "HIVE_SERVER-START", "HIVE_METASTORE-START", "HUE_SERVER-START",
+        "NODEMANAGER-START", "RESOURCEMANAGER-START", "ZOOKEEPER_SERVER-START",
+        "MYSQL_SERVER-START", "OOZIE_SERVER-START", "PIG-START", "SQOOP-START",
+        "WEBHCAT_SERVER-START", "FLUME_HANDLER-START"],
+    "MAPREDUCE_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "OOZIE_SERVICE_CHECK-SERVICE_CHECK": ["OOZIE_SERVER-START"],
+    "WEBHCAT_SERVICE_CHECK-SERVICE_CHECK": ["WEBHCAT_SERVER-START"],
+    "HBASE_SERVICE_CHECK-SERVICE_CHECK": ["HBASE_MASTER-START", "HBASE_REGIONSERVER-START"],
+    "HIVE_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START", "HIVE_METASTORE-START"],
+    "HCAT_SERVICE_CHECK-SERVICE_CHECK": ["HIVE_SERVER-START"],
+    "PIG_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "SQOOP_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "ZOOKEEPER_SERVICE_CHECK-SERVICE_CHECK": ["ZOOKEEPER_SERVER-START"],
+    "ZOOKEEPER_QUORUM_SERVICE_CHECK-SERVICE_CHECK": ["ZOOKEEPER_SERVER-START"],
+    "STORM_SERVICE_CHECK-SERVICE_CHECK": ["NIMBUS-START", "SUPERVISOR-START", "STORM_UI_SERVER-START",
+        "DRPC_SERVER-START"],
+    "FLUME_SERVICE_CHECK-SERVICE_CHECK": ["FLUME_HANDLER-START"],
+    "FALCON_SERVICE_CHECK-SERVICE_CHECK": ["FALCON_SERVER-START"],
+    "ZOOKEEPER_SERVER-STOP" : ["HBASE_MASTER-STOP", "HBASE_REGIONSERVER-STOP"],
+    "HBASE_MASTER-STOP": ["HBASE_REGIONSERVER-STOP"],
+    "NIMBUS-STOP" : ["SUPERVISOR-STOP", "STORM_UI_SERVER-STOP", "DRPC_SERVER-STOP"]
+  },
+  "_comment" : "GLUSTERFS-specific dependencies",
+  "optional_glusterfs": {
+    "HBASE_MASTER-START": ["PEERSTATUS-START"],
+    "GLUSTERFS_SERVICE_CHECK-SERVICE_CHECK": ["PEERSTATUS-START"]
+  },
+  "_comment" : "Dependencies that are used when GLUSTERFS is not present in cluster",
+  "optional_no_glusterfs": {
+    "SECONDARY_NAMENODE-START": ["NAMENODE-START"],
+    "RESOURCEMANAGER-START": ["NAMENODE-START", "DATANODE-START"],
+    "NODEMANAGER-START": ["NAMENODE-START", "DATANODE-START", "RESOURCEMANAGER-START"],
+    "HISTORYSERVER-START": ["NAMENODE-START", "DATANODE-START"],
+    "HBASE_MASTER-START": ["NAMENODE-START", "DATANODE-START"],
+    "APP_TIMELINE_SERVER-START": ["NAMENODE-START", "DATANODE-START"],
+    "FALCON_SERVER-START": ["NAMENODE-START", "DATANODE-START"],
+    "FALCON_SERVICE_CHECK-SERVICE_CHECK": ["FALCON_SERVER-START"],
+    "HIVE_SERVER-START": ["DATANODE-START"],
+    "WEBHCAT_SERVER-START": ["DATANODE-START"],
+    "NAGIOS_SERVER-START": ["NAMENODE-START", "SECONDARY_NAMENODE-START",
+        "DATANODE-START", "RESOURCEMANAGER-START", "NODEMANAGER-START", "HISTORYSERVER-START"],
+    "HDFS_SERVICE_CHECK-SERVICE_CHECK": ["NAMENODE-START", "DATANODE-START",
+        "SECONDARY_NAMENODE-START"],
+    "MAPREDUCE2_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START",
+        "RESOURCEMANAGER-START", "HISTORYSERVER-START", "YARN_SERVICE_CHECK-SERVICE_CHECK"],
+    "YARN_SERVICE_CHECK-SERVICE_CHECK": ["NODEMANAGER-START", "RESOURCEMANAGER-START"],
+    "RESOURCEMANAGER_SERVICE_CHECK-SERVICE_CHECK": ["RESOURCEMANAGER-START"],
+    "PIG_SERVICE_CHECK-SERVICE_CHECK": ["RESOURCEMANAGER-START", "NODEMANAGER-START"],
+    "NAMENODE-STOP": ["RESOURCEMANAGER-STOP", "NODEMANAGER-STOP",
+        "HISTORYSERVER-STOP", "HBASE_MASTER-STOP", "FALCON_SERVER-STOP"],
+    "DATANODE-STOP": ["RESOURCEMANAGER-STOP", "NODEMANAGER-STOP",
+        "HISTORYSERVER-STOP", "HBASE_MASTER-STOP", "FALCON_SERVER-STOP"]
+  },
+  "_comment" : "Dependencies that are used in HA NameNode cluster",
+  "namenode_optional_ha": {
+    "NAMENODE-START": ["ZKFC-START", "JOURNALNODE-START", "ZOOKEEPER_SERVER-START"],
+    "ZKFC-START": ["ZOOKEEPER_SERVER-START"],
+    "NAGIOS_SERVER-START": ["ZKFC-START", "JOURNALNODE-START"]
+  },
+  "_comment" : "Dependencies that are used in ResourceManager HA cluster",
+  "resourcemanager_optional_ha" : {
+    "RESOURCEMANAGER-START": ["ZOOKEEPER_SERVER-START"]
+  }
+}
+

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

@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>FALCON</name>
+      <displayName>Falcon</displayName>
+      <comment>Data management and processing platform</comment>
+      <version>0.6.0.2.2.0.0</version>
+    </service>
+  </services>
+</metainfo>

+ 40 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/FLUME/metainfo.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>FLUME</name>
+      <displayName>Flume</displayName>
+      <comment>Data management and processing platform</comment>
+      <version>1.5.0.1.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>flume_2_9_9_9_98</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

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

@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>HBASE</name>
+      <displayName>HBase</displayName>
+      <comment>Non-relational distributed database and centralized service for configuration management &amp;
+        synchronization
+      </comment>
+      <version>0.98.4.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hbase_2_9_9_9_98</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

+ 29 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/hadoop-env.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<configuration>
+  <property>
+    <name>rpm_version</name>
+    <value>2.9.9.9-98</value>
+    <description>Hadoop RPM version</description>
+  </property>
+</configuration>

+ 34 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/HDFS/configuration/hdfs-site.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!--
+   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.
+-->
+
+<!-- Put site-specific property overrides in this file. -->
+
+<configuration supports_final="true">
+
+  <property>
+    <name>dfs.hosts.exclude</name>
+    <value>/usr/hdp/2.9.9.9-98/etc/hadoop/conf/dfs.exclude</value>
+    <description>Names a file that contains a list of hosts that are
+      not permitted to connect to the namenode.  The full pathname of the
+      file must be specified.  If the value is empty, no hosts are
+      excluded.</description>
+  </property>
+
+</configuration>

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

@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>HDFS</name>
+      <displayName>HDFS</displayName>
+      <comment>Apache Hadoop Distributed File System</comment>
+      <version>2.6.0.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hadoop_2_9_9_9_98</name>
+            </package>
+            <package>
+              <name>hadoop-lzo</name>
+            </package>
+          </packages>
+        </osSpecific>
+        
+        <osSpecific>
+          <osFamily>redhat5,redhat6,suse11</osFamily>
+          <packages>
+            <package>
+              <name>snappy</name>
+            </package>
+            <package>
+              <name>snappy-devel</name>
+            </package>
+            <package>
+              <name>lzo</name>
+            </package>
+            <package>
+              <name>hadoop-lzo-native</name>
+            </package>
+            <package>
+              <name>hadoop_2_9_9_9_98-libhdfs</name>
+            </package>
+            <package>
+              <name>ambari-log4j</name>
+            </package>
+          </packages>
+        </osSpecific>
+            
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

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

@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>HIVE</name>
+      <comment>Data warehouse system for ad-hoc queries &amp; analysis of large datasets and table &amp; storage management service</comment>
+      <version>0.14.0.2.9.9.9</version>
+    </service>
+
+    <service>
+      <name>HCATALOG</name>
+      <comment>This is comment for HCATALOG service</comment>
+      <version>0.14.0.2.9.9.9</version>
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hive_2_9_9_9_98-hcatalog</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+    </service>
+
+  </services>
+</metainfo>

+ 45 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/OOZIE/configuration/oozie-site.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+        
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<configuration supports_final="true">
+
+  <property>
+    <name>oozie.service.HadoopAccessorService.hadoop.configurations</name>
+    <value>*=/usr/hdp/2.9.9.9-98/etc/hadoop/conf</value>
+    <description>
+      Comma separated AUTHORITY=HADOOP_CONF_DIR, where AUTHORITY is the HOST:PORT of
+      the Hadoop service (JobTracker, HDFS). The wildcard '*' configuration is
+      used when there is no exact match for an authority. The HADOOP_CONF_DIR contains
+      the relevant Hadoop *-site.xml files. If the path is relative is looked within
+      the Oozie configuration directory; though the path can be absolute (i.e. to point
+      to Hadoop client conf/ directories in the local filesystem.
+    </description>
+  </property>
+
+  <property>
+    <name>oozie.service.coord.check.maximum.frequency</name>
+    <value>false</value>
+    <description>
+      When true, Oozie will reject any coordinators with a frequency faster than 5 minutes.  It is not recommended to disable
+      this check or submit coordinators with frequencies faster than 5 minutes: doing so can cause unintended behavior and
+      additional system stress.
+    </description>
+  </property>
+
+</configuration>

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

@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>OOZIE</name>
+      <comment>System for workflow coordination and execution of Apache Hadoop jobs.  This also includes the installation of the optional Oozie Web Console which relies on and will install the &lt;a target="_blank" href="http://www.sencha.com/legal/open-source-faq/"&gt;ExtJS&lt;/a&gt; Library.
+      </comment>
+      <version>4.1.0.2.2.0.0</version>
+    </service>
+  </services>
+</metainfo>

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

@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>PIG</name>
+      <displayName>Pig</displayName>
+      <comment>Scripting platform for analyzing large datasets</comment>
+      <version>0.14.0.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>pig_2_9_9_9_98</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+
+    </service>
+  </services>
+</metainfo>

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

@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>SQOOP</name>
+      <comment>Tool for transferring bulk data between Apache Hadoop and
+        structured data stores such as relational databases
+      </comment>
+      <version>1.4.5.2.2</version>
+    </service>
+  </services>
+</metainfo>

+ 29 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/storm-env.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<configuration>
+  <property>
+    <name>rest_lib_dir</name>
+    <value>/usr/lib/storm/external/storm-rest</value>
+    <description></description>
+  </property>
+</configuration>

+ 54 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/configuration/storm-site.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * 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.
+ */
+-->
+
+<configuration supports_final="true">
+
+
+  <property>
+    <name>nimbus.childopts</name>
+    <value>-Xmx1024m -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf -javaagent:/usr/lib/storm/external/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8649,wireformat31x=true,mode=multicast,config=/usr/lib/storm/external/storm-jmxetric/conf/jmxetric-conf.xml,process=Nimbus_JVM</value>
+    <description>This parameter is used by the storm-deploy project to configure the jvm options for the nimbus daemon.</description>
+  </property>
+
+  <property>
+    <name>worker.childopts</name>
+    <value>-Xmx768m -javaagent:/usr/lib/storm/external/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8650,wireformat31x=true,mode=multicast,config=/usr/lib/storm/external/storm-jmxetric/conf/jmxetric-conf.xml,process=Worker_%ID%_JVM</value>
+    <description>The jvm opts provided to workers launched by this supervisor. All \"%ID%\" substrings are replaced with an identifier for this worker.</description>
+  </property>
+
+
+
+  <property>
+    <name>ui.childopts</name>
+    <value>-Xmx768m -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf</value>
+    <description>Childopts for Storm UI Java process.</description>
+  </property>
+
+  <property>
+    <name>supervisor.childopts</name>
+    <value>-Xmx256m -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=56431 -javaagent:/usr/lib/storm/external/storm-jmxetric/lib/jmxetric-1.0.4.jar=host=localhost,port=8650,wireformat31x=true,mode=multicast,config=/usr/lib/storm/external/storm-jmxetric/conf/jmxetric-conf.xml,process=Supervisor_JVM</value>
+    <description>This parameter is used by the storm-deploy project to configure the jvm options for the supervisor daemon.</description>
+  </property>
+
+
+
+</configuration>

+ 29 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/STORM/metainfo.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>STORM</name>
+      <displayName>Storm</displayName>
+      <comment>Apache Hadoop Stream processing framework</comment>
+      <version>0.9.3.2.2.0.0</version>
+    </service>
+  </services>
+</metainfo>

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

@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>TEZ</name>
+      <displayName>Tez</displayName>
+      <comment>Tez is the next generation Hadoop Query Processing framework written on top of YARN.</comment>
+      <version>0.6.0.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>tez_2_9_9_9_98</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

+ 59 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/WEBHCAT/configuration/webhcat-site.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<!-- The default settings for Templeton. -->
+<!-- Edit templeton-site.xml to change settings for your local -->
+<!-- install. -->
+
+<configuration supports_final="true">
+
+  <property>
+    <name>templeton.hadoop.conf.dir</name>
+    <value>/usr/hdp/2.9.9.9-98/etc/hadoop/conf</value>
+    <description>The path to the Hadoop configuration.</description>
+  </property>
+
+  <property>
+    <name>templeton.jar</name>
+    <value>/usr/hdp/2.9.9.9-98/hcatalog/share/webhcat/svr/webhcat.jar</value>
+    <description>The path to the Templeton jar file.</description>
+  </property>
+
+  <property>
+    <name>templeton.libjars</name>
+    <value>/usr/hdp/2.9.9.9-98/zookeeper/zookeeper.jar</value>
+    <description>Jars to add the the classpath.</description>
+  </property>
+
+
+  <property>
+    <name>templeton.hadoop</name>
+    <value>/usr/hdp/2.9.9.9-98/hadoop/bin/hadoop</value>
+    <description>The path to the Hadoop executable.</description>
+  </property>
+
+
+  <property>
+    <name>templeton.hcat</name>
+    <value>/usr/hdp/2.9.9.9-98/hive/bin/hcat</value>
+    <description>The path to the hcatalog executable.</description>
+  </property>
+
+
+</configuration>

+ 44 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/WEBHCAT/metainfo.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>WEBHCAT</name>
+      <comment>This is comment for WEBHCAT service</comment>
+      <version>0.14.0.2.9.9.9</version>
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hive_2_9_9_9_98-webhcat</name>
+            </package>
+            <package>
+              <name>webhcat-tar-hive</name>
+            </package>
+            <package>
+              <name>webhcat-tar-pig</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

+ 36 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration-mapred/mapred-site.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!--
+   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.
+-->
+
+<!-- Put site-specific property overrides in this file. -->
+
+<configuration supports_final="true" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <property>
+    <name>mapreduce.admin.user.env</name>
+    <value>LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:/usr/hdp/2.9.9.9-98/hadoop/lib/native/Linux-amd64-64</value>
+    <description>
+      Additional execution environment entries for map and reduce task processes.
+      This is not an additive property. You must preserve the original value if
+      you want your map and reduce tasks to have access to native libraries (compression, etc)
+    </description>
+  </property>
+
+
+</configuration>

+ 35 - 0
ambari-server/src/main/resources/stacks/HDP/2.2/services/YARN/configuration/yarn-site.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   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.
+-->
+
+<!-- Put site-specific property overrides in this file. -->
+
+<configuration supports_final="true" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <property>
+    <name>yarn.resourcemanager.nodes.exclude-path</name>
+    <value>/usr/hdp/2.9.9.9-98/etc/hadoop/conf/yarn.exclude</value>
+    <description>
+      Names a file that contains a list of hosts that are
+      not permitted to connect to the resource manager.  The full pathname of the
+      file must be specified.  If the value is empty, no hosts are
+      excluded.
+    </description>
+  </property>
+
+</configuration>

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

@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>YARN</name>
+      <displayName>YARN</displayName>
+      <comment>Apache Hadoop NextGen MapReduce (YARN)</comment>
+      <version>2.6.0.2.9.9.9</version>
+      <components>
+        <components>
+          <component>
+            <name>APP_TIMELINE_SERVER</name>
+            <cardinality>1</cardinality>
+          </component>
+        </components>
+      </components>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hadoop_2_9_9_9_98-yarn</name>
+            </package>
+            <package>
+              <name>hadoop_2_9_9_9_98-mapreduce</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+    </service>
+
+    <service>
+      <name>MAPREDUCE2</name>
+      <displayName>MapReduce2</displayName>
+      <comment>Apache Hadoop NextGen MapReduce (YARN)</comment>
+      <version>2.6.0.2.9.9.9</version>
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>hadoop_2_9_9_9_98-mapreduce</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+      <configuration-dir>configuration-mapred</configuration-dir>
+
+    </service>
+
+  </services>
+</metainfo>

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

@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>ZOOKEEPER</name>
+      <displayName>ZooKeeper</displayName>
+      <comment>Centralized service which provides highly reliable distributed coordination</comment>
+      <version>3.4.5.2.9.9.9</version>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>any</osFamily>
+          <packages>
+            <package>
+              <name>zookeeper_2_9_9_9_98</name>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+    </service>
+  </services>
+</metainfo>

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProviderTest.java

@@ -98,7 +98,7 @@ public class AmbariPrivilegeResourceProviderTest {
   @Before
   public void resetGlobalMocks() {
     ViewRegistry.initInstance(ViewRegistryTest.getRegistry(viewDAO, viewInstanceDAO, userDAO,
-        memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList));
+        memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null));
     reset(privilegeDAO, userDAO, groupDAO, principalDAO, permissionDAO, resourceDAO, clusterDAO, handlerList);
   }
 

+ 413 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessorTest.java

@@ -0,0 +1,413 @@
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.StackServiceResponse;
+import org.apache.ambari.server.state.DependencyInfo;
+import org.easymock.EasyMockSupport;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+/**
+ * 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.
+ */
+
+public class BaseBlueprintProcessorTest {
+
+  @Before
+  public void setUp() throws Exception {
+    BaseBlueprintProcessor.stackInfo = null;
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependencies() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo hCatDependency = new TestDependencyInfo("WEBHCAT/HCAT");
+    final DependencyInfo yarnClientDependency = new TestDependencyInfo("YARN/YARN_CLIENT");
+    final DependencyInfo tezClientDependency = new TestDependencyInfo("TEZ/TEZ_CLIENT");
+    final DependencyInfo mapReduceTwoClientDependency = new TestDependencyInfo("YARN/MAPREDUCE2_CLIENT");
+    final DependencyInfo oozieClientDependency = new TestDependencyInfo("OOZIE/OOZIE_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(hCatDependency);
+            setOfDependencies.add(yarnClientDependency);
+            setOfDependencies.add(tezClientDependency);
+            setOfDependencies.add(mapReduceTwoClientDependency);
+            setOfDependencies.add(oozieClientDependency);
+
+            return setOfDependencies;
+          }
+
+            return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+                 0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+                 5, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for HCAT",
+                 "HCATALOG", testStack.getDependencyConditionalServiceMap().get(hCatDependency));
+    assertEquals("Incorrect service dependency for YARN_CLIENT",
+                 "YARN", testStack.getDependencyConditionalServiceMap().get(yarnClientDependency));
+    assertEquals("Incorrect service dependency for TEZ_CLIENT",
+                 "TEZ", testStack.getDependencyConditionalServiceMap().get(tezClientDependency));
+    assertEquals("Incorrect service dependency for MAPREDUCE2_CLIENT",
+                 "MAPREDUCE2", testStack.getDependencyConditionalServiceMap().get(mapReduceTwoClientDependency));
+    assertEquals("Incorrect service dependency for OOZIE_CLIENT",
+                 "OOZIE", testStack.getDependencyConditionalServiceMap().get(oozieClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependenciesNoHCAT() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo yarnClientDependency = new TestDependencyInfo("YARN/YARN_CLIENT");
+    final DependencyInfo tezClientDependency = new TestDependencyInfo("TEZ/TEZ_CLIENT");
+    final DependencyInfo mapReduceTwoClientDependency = new TestDependencyInfo("YARN/MAPREDUCE2_CLIENT");
+    final DependencyInfo oozieClientDependency = new TestDependencyInfo("OOZIE/OOZIE_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(yarnClientDependency);
+            setOfDependencies.add(tezClientDependency);
+            setOfDependencies.add(mapReduceTwoClientDependency);
+            setOfDependencies.add(oozieClientDependency);
+
+            return setOfDependencies;
+          }
+
+          return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+      0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+      4, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for YARN_CLIENT",
+      "YARN", testStack.getDependencyConditionalServiceMap().get(yarnClientDependency));
+    assertEquals("Incorrect service dependency for TEZ_CLIENT",
+      "TEZ", testStack.getDependencyConditionalServiceMap().get(tezClientDependency));
+    assertEquals("Incorrect service dependency for MAPREDUCE2_CLIENT",
+      "MAPREDUCE2", testStack.getDependencyConditionalServiceMap().get(mapReduceTwoClientDependency));
+    assertEquals("Incorrect service dependency for OOZIE_CLIENT",
+      "OOZIE", testStack.getDependencyConditionalServiceMap().get(oozieClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependenciesNoYarnClient() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo hCatDependency = new TestDependencyInfo("WEBHCAT/HCAT");
+    final DependencyInfo tezClientDependency = new TestDependencyInfo("TEZ/TEZ_CLIENT");
+    final DependencyInfo mapReduceTwoClientDependency = new TestDependencyInfo("YARN/MAPREDUCE2_CLIENT");
+    final DependencyInfo oozieClientDependency = new TestDependencyInfo("OOZIE/OOZIE_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(hCatDependency);
+            setOfDependencies.add(tezClientDependency);
+            setOfDependencies.add(mapReduceTwoClientDependency);
+            setOfDependencies.add(oozieClientDependency);
+
+            return setOfDependencies;
+          }
+
+          return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+      0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+      4, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for HCAT",
+      "HCATALOG", testStack.getDependencyConditionalServiceMap().get(hCatDependency));
+    assertEquals("Incorrect service dependency for TEZ_CLIENT",
+      "TEZ", testStack.getDependencyConditionalServiceMap().get(tezClientDependency));
+    assertEquals("Incorrect service dependency for MAPREDUCE2_CLIENT",
+      "MAPREDUCE2", testStack.getDependencyConditionalServiceMap().get(mapReduceTwoClientDependency));
+    assertEquals("Incorrect service dependency for OOZIE_CLIENT",
+      "OOZIE", testStack.getDependencyConditionalServiceMap().get(oozieClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependenciesNoTezClient() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo hCatDependency = new TestDependencyInfo("WEBHCAT/HCAT");
+    final DependencyInfo yarnClientDependency = new TestDependencyInfo("YARN/YARN_CLIENT");
+    final DependencyInfo mapReduceTwoClientDependency = new TestDependencyInfo("YARN/MAPREDUCE2_CLIENT");
+    final DependencyInfo oozieClientDependency = new TestDependencyInfo("OOZIE/OOZIE_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(hCatDependency);
+            setOfDependencies.add(yarnClientDependency);
+            setOfDependencies.add(mapReduceTwoClientDependency);
+            setOfDependencies.add(oozieClientDependency);
+
+            return setOfDependencies;
+          }
+
+          return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+      0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+      4, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for HCAT",
+      "HCATALOG", testStack.getDependencyConditionalServiceMap().get(hCatDependency));
+    assertEquals("Incorrect service dependency for YARN_CLIENT",
+      "YARN", testStack.getDependencyConditionalServiceMap().get(yarnClientDependency));
+    assertEquals("Incorrect service dependency for MAPREDUCE2_CLIENT",
+      "MAPREDUCE2", testStack.getDependencyConditionalServiceMap().get(mapReduceTwoClientDependency));
+    assertEquals("Incorrect service dependency for OOZIE_CLIENT",
+      "OOZIE", testStack.getDependencyConditionalServiceMap().get(oozieClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependenciesNoMapReduceClient() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo hCatDependency = new TestDependencyInfo("WEBHCAT/HCAT");
+    final DependencyInfo yarnClientDependency = new TestDependencyInfo("YARN/YARN_CLIENT");
+    final DependencyInfo tezClientDependency = new TestDependencyInfo("TEZ/TEZ_CLIENT");
+    final DependencyInfo oozieClientDependency = new TestDependencyInfo("OOZIE/OOZIE_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(hCatDependency);
+            setOfDependencies.add(yarnClientDependency);
+            setOfDependencies.add(tezClientDependency);
+            setOfDependencies.add(oozieClientDependency);
+
+            return setOfDependencies;
+          }
+
+          return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+      0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+      4, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for HCAT",
+      "HCATALOG", testStack.getDependencyConditionalServiceMap().get(hCatDependency));
+    assertEquals("Incorrect service dependency for YARN_CLIENT",
+      "YARN", testStack.getDependencyConditionalServiceMap().get(yarnClientDependency));
+    assertEquals("Incorrect service dependency for TEZ_CLIENT",
+      "TEZ", testStack.getDependencyConditionalServiceMap().get(tezClientDependency));
+    assertEquals("Incorrect service dependency for OOZIE_CLIENT",
+      "OOZIE", testStack.getDependencyConditionalServiceMap().get(oozieClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  @Test
+  public void testStackRegisterConditionalDependenciesNoOozieClient() throws Exception {
+    EasyMockSupport mockSupport = new EasyMockSupport();
+    AmbariManagementController mockMgmtController =
+      mockSupport.createMock(AmbariManagementController.class);
+
+    // setup mock expectations
+    expect(mockMgmtController.getStackServices(isA(Set.class))).andReturn(Collections.<StackServiceResponse>emptySet());
+
+    // test dependencies
+    final DependencyInfo hCatDependency = new TestDependencyInfo("WEBHCAT/HCAT");
+    final DependencyInfo yarnClientDependency = new TestDependencyInfo("YARN/YARN_CLIENT");
+    final DependencyInfo tezClientDependency = new TestDependencyInfo("TEZ/TEZ_CLIENT");
+    final DependencyInfo mapReduceTwoClientDependency = new TestDependencyInfo("YARN/MAPREDUCE2_CLIENT");
+
+    mockSupport.replayAll();
+
+    // create stack for testing
+    BaseBlueprintProcessor.Stack testStack =
+      new BaseBlueprintProcessor.Stack("HDP", "2.1", mockMgmtController) {
+        @Override
+        public Collection<DependencyInfo> getDependenciesForComponent(String component) {
+          // simulate the dependencies in a given stack by overriding this method
+          if (component.equals("NAGIOS_SERVER")) {
+            Set<DependencyInfo> setOfDependencies = new HashSet<DependencyInfo>();
+
+            setOfDependencies.add(hCatDependency);
+            setOfDependencies.add(yarnClientDependency);
+            setOfDependencies.add(tezClientDependency);
+            setOfDependencies.add(mapReduceTwoClientDependency);
+
+            return setOfDependencies;
+          }
+
+          return Collections.emptySet();
+        }
+      };
+
+    assertEquals("Initial conditional dependency map should be empty",
+      0, testStack.getDependencyConditionalServiceMap().size());
+
+    testStack.registerConditionalDependencies();
+
+    assertEquals("Set of conditional service mappings is an incorrect size",
+      4, testStack.getDependencyConditionalServiceMap().size());
+
+    assertEquals("Incorrect service dependency for HCAT",
+      "HCATALOG", testStack.getDependencyConditionalServiceMap().get(hCatDependency));
+    assertEquals("Incorrect service dependency for YARN_CLIENT",
+      "YARN", testStack.getDependencyConditionalServiceMap().get(yarnClientDependency));
+    assertEquals("Incorrect service dependency for TEZ_CLIENT",
+      "TEZ", testStack.getDependencyConditionalServiceMap().get(tezClientDependency));
+    assertEquals("Incorrect service dependency for MAPREDUCE2_CLIENT",
+      "MAPREDUCE2", testStack.getDependencyConditionalServiceMap().get(mapReduceTwoClientDependency));
+
+    mockSupport.verifyAll();
+  }
+
+
+  /**
+   * Convenience class for easier setup/initialization of dependencies
+   * for unit testing.
+   */
+  private static class TestDependencyInfo extends DependencyInfo {
+    TestDependencyInfo(String dependencyName) {
+      setName(dependencyName);
+    }
+  }
+}

+ 76 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java

@@ -0,0 +1,76 @@
+/**
+ * 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.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.ambari.server.controller.internal.StackAdvisorResourceProvider.CONFIGURATIONS_PROPERTY_ID;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class StackAdvisorResourceProviderTest {
+
+  @Test
+  public void testCalculateConfigurations() throws Exception {
+
+    Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
+    Set<String> propertyIds = Collections.emptySet();
+    AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
+    RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
+        keyPropertyIds, ambariManagementController);
+
+    Request request = mock(Request.class);
+    Set<Map<String, Object>> propertiesSet = new HashSet<Map<String, Object>>();
+    Map<String, Object> propertiesMap = new HashMap<String, Object>();
+    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string");
+    List<Object> array = new ArrayList<Object>();
+    array.add("array1");
+    array.add("array2");
+    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", array);
+    propertiesSet.add(propertiesMap);
+
+    doReturn(propertiesSet).when(request).getProperties();
+
+    Map<String, Map<String, Map<String, String>>> calculatedConfigurations = provider.calculateConfigurations(request);
+
+    assertNotNull(calculatedConfigurations);
+    assertEquals(1, calculatedConfigurations.size());
+    Map<String, Map<String, String>> site = calculatedConfigurations.get("site");
+    assertNotNull(site);
+    assertEquals(1, site.size());
+    Map<String, String> properties = site.get("properties");
+    assertNotNull(properties);
+    assertEquals(2, properties.size());
+    assertEquals("string", properties.get("string_prop"));
+    assertEquals("[array1, array2]", properties.get("array_prop"));
+  }
+}

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewPrivilegeResourceProviderTest.java

@@ -90,7 +90,7 @@ public class ViewPrivilegeResourceProviderTest {
   public void resetGlobalMocks() {
 
     ViewRegistry.initInstance(ViewRegistryTest.getRegistry(viewDAO, viewInstanceDAO, userDAO,
-        memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList));
+        memberDAO, privilegeDAO, resourceDAO, resourceTypeDAO, securityHelper, handlerList, null, null));
     reset(privilegeDAO, userDAO, groupDAO, principalDAO, permissionDAO, resourceDAO, handlerList);
   }
 

+ 50 - 0
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderBaseTest.java

@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.security.authorization;
+
+import org.apache.commons.io.FileUtils;
+import org.easymock.EasyMockSupport;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class AmbariLdapAuthenticationProviderBaseTest extends EasyMockSupport {
+
+  private static final Log logger = LogFactory.getLog(AmbariLdapAuthenticationProviderBaseTest.class);
+
+  protected static void createCleanApacheDSContainerWorkDir() throws IOException{
+    // Set ApacheDsContainer's work dir under the current folder (Jenkins' job workspace) instead of the default /tmp/apacheds-spring-security. See AMBARI-7180
+    SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
+    String timestamp = sdf.format(new Date());
+    final String workParent = new File(".").getAbsolutePath() + File.separator + "target" + File.separator + timestamp;
+    new File(workParent).mkdirs();
+    // The folder structure looks like {job-root}/target/{timestamp}/apacheds-spring-security
+    final String apacheDSWorkDir = workParent + File.separator + "apacheds-spring-security";
+    FileUtils.deleteDirectory(new File(apacheDSWorkDir));
+    System.setProperty("apacheDSWorkDir", apacheDSWorkDir );
+    logger.info("System property apacheDSWorkDir was set to " + apacheDSWorkDir);
+
+  }
+
+}

+ 2 - 2
ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProviderForDNWithSpaceTest.java

@@ -24,7 +24,6 @@ import com.google.inject.persist.PersistService;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.dao.UserDAO;
-import org.apache.ambari.server.orm.entities.UserEntity;
 import org.apache.ambari.server.security.ClientSecurityType;
 import org.junit.*;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -34,7 +33,7 @@ import org.springframework.security.ldap.server.ApacheDSContainer;
 
 import static org.junit.Assert.*;
 
-public class AmbariLdapAuthenticationProviderForDNWithSpaceTest {
+public class AmbariLdapAuthenticationProviderForDNWithSpaceTest extends AmbariLdapAuthenticationProviderBaseTest{
   private static ApacheDSContainer apacheDSContainer;
   private static Injector injector;
 
@@ -47,6 +46,7 @@ public class AmbariLdapAuthenticationProviderForDNWithSpaceTest {
 
   @BeforeClass
   public static void beforeClass() throws Exception{
+    createCleanApacheDSContainerWorkDir();
     apacheDSContainer = new ApacheDSContainer("dc=ambari,dc=the apache,dc=org", "classpath:/users_for_dn_with_space.ldif");
     apacheDSContainer.setPort(33389);
     apacheDSContainer.afterPropertiesSet();

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů