Parcourir la source

AMBARI-1108 - PUT call to change the state on host_components collection returns 200 (no op), even though GET with the same predicate returns a number of host_components. (Tom Beerbower via mahadev)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1431843 13f79535-47bb-0310-9956-ffa450edef68
Mahadev Konar il y a 12 ans
Parent
commit
bb45951281
100 fichiers modifiés avec 3008 ajouts et 782 suppressions
  1. 11 0
      CHANGES.txt
  2. 2 2
      ambari-agent/conf/unix/ambari-agent.ini
  3. 15 0
      ambari-agent/conf/unix/ambari-env.sh
  4. 21 7
      ambari-agent/pom.xml
  5. 15 0
      ambari-agent/src/main/package/rpm/postinstall.sh
  6. 15 0
      ambari-agent/src/main/package/rpm/preinstall.sh
  7. 3 1
      ambari-agent/src/main/puppet/modules/configgenerator/manifests/configfile.pp
  8. 20 8
      ambari-agent/src/main/puppet/modules/hdp-ganglia/manifests/server.pp
  9. 23 6
      ambari-agent/src/main/puppet/modules/hdp-hadoop/manifests/init.pp
  10. 2 2
      ambari-agent/src/main/puppet/modules/hdp-hadoop/manifests/params.pp
  11. 1 1
      ambari-agent/src/main/puppet/modules/hdp-hbase/manifests/params.pp
  12. 1 1
      ambari-agent/src/main/puppet/modules/hdp-hcat-old/manifests/params.pp
  13. 1 1
      ambari-agent/src/main/puppet/modules/hdp-hive/files/startHiveserver2.sh
  14. 24 21
      ambari-agent/src/main/puppet/modules/hdp-hive/manifests/hive/service_check.pp
  15. 3 3
      ambari-agent/src/main/puppet/modules/hdp-hive/manifests/params.pp
  16. 6 4
      ambari-agent/src/main/puppet/modules/hdp-mysql/files/startMysql.sh
  17. 3 1
      ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/params.pp
  18. 7 4
      ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server.pp
  19. 1 0
      ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server/config.pp
  20. 46 10
      ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server/packages.pp
  21. 3 3
      ambari-agent/src/main/puppet/modules/hdp-nagios/templates/hadoop-services.cfg.erb
  22. 1 1
      ambari-agent/src/main/puppet/modules/hdp-nagios/templates/nagios.cfg.erb
  23. 33 0
      ambari-agent/src/main/puppet/modules/hdp-nagios/templates/resource.cfg.erb
  24. 1 1
      ambari-agent/src/main/puppet/modules/hdp-oozie/manifests/service.pp
  25. 2 2
      ambari-agent/src/main/puppet/modules/hdp-templeton/manifests/params.pp
  26. 9 1
      ambari-agent/src/main/puppet/modules/hdp/lib/puppet/parser/functions/hdp_default.rb
  27. 31 1
      ambari-agent/src/main/puppet/modules/hdp/manifests/params.pp
  28. 2 2
      ambari-agent/src/main/python/ambari_agent/AmbariConfig.py
  29. 15 0
      ambari-agent/src/main/python/ambari_agent/Grep.py
  30. 16 6
      ambari-agent/src/main/python/ambari_agent/Hardware.py
  31. 20 2
      ambari-agent/src/main/python/ambari_agent/NetUtil.py
  32. 60 0
      ambari-agent/src/main/python/ambari_agent/machine.py
  33. 2 2
      ambari-agent/src/main/python/ambari_agent/main.py
  34. 20 9
      ambari-agent/src/main/python/ambari_agent/manifestGenerator.py
  35. 16 2
      ambari-agent/src/main/python/ambari_agent/rolesToClass.dict
  36. 16 0
      ambari-agent/src/main/python/ambari_agent/security.py
  37. 15 0
      ambari-agent/src/main/python/ambari_agent/serviceStates.dict
  38. 15 0
      ambari-agent/src/main/python/ambari_agent/servicesToPidNames.dict
  39. 1 1
      ambari-agent/src/test/python/TestActionQueue.py
  40. 1 1
      ambari-agent/src/test/python/TestNetUtil.py
  41. 2 2
      ambari-project/pom.xml
  42. 15 0
      ambari-server/conf/unix/ambari-env.sh
  43. 17 0
      ambari-server/conf/unix/ambari.properties
  44. 2 2
      ambari-server/derby.log
  45. 13 0
      ambari-server/exclude.xml
  46. 26 20
      ambari-server/pom.xml
  47. 20 1
      ambari-server/sbin/ambari-server
  48. 0 18
      ambari-server/src/examples/spec.json
  49. 17 0
      ambari-server/src/main/conf/ambari.properties
  50. 34 0
      ambari-server/src/main/java/org/apache/ambari/server/DuplicateResourceException.java
  51. 4 0
      ambari-server/src/main/java/org/apache/ambari/server/HostNotFoundException.java
  52. 44 0
      ambari-server/src/main/java/org/apache/ambari/server/ParentObjectNotFoundException.java
  53. 1 0
      ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java
  54. 48 56
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java
  55. 42 4
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
  56. 38 5
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java
  57. 51 16
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java
  58. 53 12
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
  59. 1 0
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/RequestHandler.java
  60. 35 4
      ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
  61. 11 7
      ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java
  62. 16 15
      ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java
  63. 32 0
      ambari-server/src/main/java/org/apache/ambari/server/api/resources/RequestResourceDefinition.java
  64. 7 0
      ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstance.java
  65. 5 0
      ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceImpl.java
  66. 241 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java
  67. 29 19
      ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
  68. 47 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java
  69. 46 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java
  70. 47 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java
  71. 47 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java
  72. 59 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java
  73. 0 7
      ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java
  74. 14 9
      ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java
  75. 40 2
      ambari-server/src/main/java/org/apache/ambari/server/api/services/Result.java
  76. 30 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultImpl.java
  77. 5 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java
  78. 176 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultStatus.java
  79. 45 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/persistence/PersistenceManager.java
  80. 94 0
      ambari-server/src/main/java/org/apache/ambari/server/api/services/persistence/PersistenceManagerImpl.java
  81. 35 9
      ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
  82. 12 4
      ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java
  83. 28 1
      ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
  84. 9 1
      ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
  85. 3 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
  86. 331 135
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
  87. 70 52
      ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
  88. 11 21
      ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java
  89. 10 9
      ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java
  90. 5 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaHostProvider.java
  91. 20 7
      ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java
  92. 24 12
      ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaReportPropertyProvider.java
  93. 18 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/MetricsMapping.java
  94. 38 16
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java
  95. 126 83
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
  96. 54 20
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
  97. 57 26
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java
  98. 97 22
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java
  99. 17 17
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
  100. 90 40
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java

+ 11 - 0
CHANGES.txt

@@ -8,6 +8,17 @@ should be listed by their full name.
 
 
   Merging AMBARI-666 to trunk.
   Merging AMBARI-666 to trunk.
 
 
+ INCOMPATIBLE CHANGES
+ 
+ NEW FEATURES
+
+ AMBARI-1108 - PUT call to change the state on host_components collection
+ returns 200 (no op), even though GET with the same predicate returns a number
+ of host_components. (Tom Beerbower via mahadev)
+
+ BUG FIXES
+
+
 AMBARI-666 branch (unreleased changes)
 AMBARI-666 branch (unreleased changes)
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 2 - 2
ambari-agent/conf/unix/ambari-agent.ini

@@ -1,7 +1,7 @@
 [server]
 [server]
 hostname=localhost
 hostname=localhost
-url_port=4080
-secured_url_port=8443
+url_port=8440
+secured_url_port=8441
 
 
 [agent]
 [agent]
 prefix=/var/lib/ambari-agent/data
 prefix=/var/lib/ambari-agent/data

+ 15 - 0
ambari-agent/conf/unix/ambari-env.sh

@@ -1,3 +1,18 @@
+# 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
+
 # To change a passphrase used by the agent adjust the line below. This value is used when no passphrase is
 # To change a passphrase used by the agent adjust the line below. This value is used when no passphrase is
 # given through environment variable
 # given through environment variable
 AMBARI_PASSPHRASE="DEV"
 AMBARI_PASSPHRASE="DEV"

+ 21 - 7
ambari-agent/pom.xml

@@ -19,21 +19,21 @@
   <parent>
   <parent>
     <groupId>org.apache.ambari</groupId>
     <groupId>org.apache.ambari</groupId>
     <artifactId>ambari-project</artifactId>
     <artifactId>ambari-project</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
     <relativePath>../ambari-project</relativePath>
     <relativePath>../ambari-project</relativePath>
   </parent>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.ambari</groupId>
   <groupId>org.apache.ambari</groupId>
   <artifactId>ambari-agent</artifactId>
   <artifactId>ambari-agent</artifactId>
   <packaging>pom</packaging>
   <packaging>pom</packaging>
-  <version>1.0.3-SNAPSHOT</version>
+  <version>1.2.0-SNAPSHOT</version>
   <name>Ambari Agent</name>
   <name>Ambari Agent</name>
   <description>Ambari Agent</description>
   <description>Ambari Agent</description>
   <properties>
   <properties>
     <final.name>${project.artifactId}-${project.version}</final.name>
     <final.name>${project.artifactId}-${project.version}</final.name>
     <package.release>1</package.release>
     <package.release>1</package.release>
     <package.prefix>/usr</package.prefix>
     <package.prefix>/usr</package.prefix>
-    <package.conf.dir>/etc/ambari-agent</package.conf.dir>
+    <package.conf.dir>/etc/ambari-agent/conf</package.conf.dir>
     <package.log.dir>/var/log/ambari-agent</package.log.dir>
     <package.log.dir>/var/log/ambari-agent</package.log.dir>
     <package.pid.dir>/var/run/ambari-agent</package.pid.dir>
     <package.pid.dir>/var/run/ambari-agent</package.pid.dir>
     <skipTests>false</skipTests>
     <skipTests>false</skipTests>
@@ -181,7 +181,7 @@
               </sources>
               </sources>
             </mapping>
             </mapping>
             <mapping>
             <mapping>
-              <directory>/etc/ambari-agent</directory>
+              <directory>${package.conf.dir}</directory>
               <filemode>755</filemode>
               <filemode>755</filemode>
               <username>root</username>
               <username>root</username>
               <groupname>root</groupname>
               <groupname>root</groupname>
@@ -193,7 +193,7 @@
             </mapping>
             </mapping>
             <mapping>
             <mapping>
               <directory>/usr/sbin</directory>
               <directory>/usr/sbin</directory>
-              <filemode>744</filemode>
+              <filemode>755</filemode>
               <username>root</username>
               <username>root</username>
               <groupname>root</groupname>
               <groupname>root</groupname>
               <sources>
               <sources>
@@ -214,7 +214,7 @@
               </sources>
               </sources>
             </mapping>
             </mapping>
             <mapping>
             <mapping>
-              <directory>/var/run/ambari-agent</directory>
+              <directory>${package.pid.dir}</directory>
               <filemode>755</filemode>
               <filemode>755</filemode>
               <username>root</username>
               <username>root</username>
               <groupname>root</groupname>
               <groupname>root</groupname>
@@ -232,7 +232,7 @@
               <groupname>root</groupname>
               <groupname>root</groupname>
             </mapping>
             </mapping>
             <mapping>
             <mapping>
-              <directory>/var/log/ambari-agent</directory>
+              <directory>${package.log.dir}</directory>
               <filemode>755</filemode>
               <filemode>755</filemode>
               <username>root</username>
               <username>root</username>
               <groupname>root</groupname>
               <groupname>root</groupname>
@@ -280,6 +280,20 @@
           </execution>
           </execution>
         </executions>
         </executions>
       </plugin>
       </plugin>
+        <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <version>0.8</version>
+            <configuration>
+                <excludes>
+                    <exclude>src/test/python/dummy*.txt</exclude>
+                </excludes>
+                <includes>
+                    <include>pom.xml</include>
+                </includes>
+            </configuration>
+        </plugin>
+
     </plugins>
     </plugins>
     <extensions>
     <extensions>
       <extension>
       <extension>

+ 15 - 0
ambari-agent/src/main/package/rpm/postinstall.sh

@@ -1 +1,16 @@
+# 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
+
 chmod 755 /usr/lib/ambari-agent/lib/facter-1.6.10/bin/facter /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/filebucket /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/pi /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/puppet /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/puppetdoc /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/ralsh /usr/lib/ambari-agent/lib/ruby-1.8.7-p370/bin/*
 chmod 755 /usr/lib/ambari-agent/lib/facter-1.6.10/bin/facter /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/filebucket /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/pi /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/puppet /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/puppetdoc /usr/lib/ambari-agent/lib/puppet-2.7.9/bin/ralsh /usr/lib/ambari-agent/lib/ruby-1.8.7-p370/bin/*

+ 15 - 0
ambari-agent/src/main/package/rpm/preinstall.sh

@@ -1,2 +1,17 @@
+# 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
+
 getent group puppet >/dev/null || groupadd -r puppet
 getent group puppet >/dev/null || groupadd -r puppet
 getent passwd puppet >/dev/null || /usr/sbin/useradd -g puppet puppet
 getent passwd puppet >/dev/null || /usr/sbin/useradd -g puppet puppet

+ 3 - 1
ambari-agent/src/main/puppet/modules/configgenerator/manifests/configfile.pp

@@ -43,7 +43,7 @@
 # Note: Set correct $modulespath in the configgenerator (or pass it as parameter)
 # Note: Set correct $modulespath in the configgenerator (or pass it as parameter)
 #
 #
 
 
-define configgenerator::configfile ($modulespath='/etc/puppet/modules', $filename, $module, $configuration) {
+define configgenerator::configfile ($modulespath='/etc/puppet/modules', $filename, $module, $configuration, $owner = "root", $group = "root") {
   $configcontent = inline_template('<!--<%=Time.now.asctime %>-->
   $configcontent = inline_template('<!--<%=Time.now.asctime %>-->
   <configuration>
   <configuration>
   <% configuration.each do |key,value| -%>
   <% configuration.each do |key,value| -%>
@@ -61,5 +61,7 @@ file {"${modulespath}/${filename}":
   ensure  => present,
   ensure  => present,
   content => $configcontent,
   content => $configcontent,
   path => "${modulespath}/${filename}",
   path => "${modulespath}/${filename}",
+  owner => $owner,
+  group => $group
 }
 }
 } 
 } 

+ 20 - 8
ambari-agent/src/main/puppet/modules/hdp-ganglia/manifests/server.pp

@@ -63,8 +63,11 @@ class hdp-ganglia::server(
   
   
   if ($service_state == 'installed_and_configured') {
   if ($service_state == 'installed_and_configured') {
     $webserver_state = 'restart'
     $webserver_state = 'restart'
+  } elsif ($service_state == 'running') {
+    $webserver_state = 'running'
   } else {
   } else {
-    $webserver_state = $service_state
+    # We are never stopping httpd
+    #$webserver_state = $service_state
   }
   }
 
 
   class { 'hdp-monitor-webserver': service_state => $webserver_state}
   class { 'hdp-monitor-webserver': service_state => $webserver_state}
@@ -87,12 +90,19 @@ class hdp-ganglia::server::packages(
   hdp::package { ['ganglia-server','ganglia-gweb','ganglia-hdp-gweb-addons']: 
   hdp::package { ['ganglia-server','ganglia-gweb','ganglia-hdp-gweb-addons']: 
     ensure      => $ensure,
     ensure      => $ensure,
     java_needed => false  
     java_needed => false  
-  } 
+  }
+
+  hdp::package { ['rrdtool']:
+        ensure      => 'absent',
+        java_needed => false,
+        before => Hdp::Package ['rrdtool-python']
+  }
+
+  hdp::package { ['rrdtool-python']:
+      ensure      => $ensure,
+      java_needed => false
+  }
 
 
-  hdp::package { ['rrdtool-python']: 
-    ensure      => $ensure,
-    java_needed => false  
-  } 
 }
 }
 
 
 class hdp-ganglia::server::files(
 class hdp-ganglia::server::files(
@@ -101,12 +111,14 @@ class hdp-ganglia::server::files(
 {
 {
 
 
 
 
-  $rrd_py_path = $hdp::params::rrd_py_path
+  $rrd_py_path = $hdp::params::rrd_py_path [$hdp::params::hdp_os_type]
   hdp::directory_recursive_create{$rrd_py_path:
   hdp::directory_recursive_create{$rrd_py_path:
     ensure => "directory"  
     ensure => "directory"  
   }
   }
 
 
-  file{'/var/www/cgi-bin/rrd.py' : 
+  $rrd_py_file_path = "${rrd_py_path}/rrd.py"
+
+  file{$rrd_py_file_path :
     ensure => $ensure,
     ensure => $ensure,
     source => "puppet:///modules/hdp-ganglia/rrd.py",
     source => "puppet:///modules/hdp-ganglia/rrd.py",
     mode   => '0755',
     mode   => '0755',

+ 23 - 6
ambari-agent/src/main/puppet/modules/hdp-hadoop/manifests/init.pp

@@ -48,7 +48,14 @@ debug('##Configs generation for hdp-hadoop')
       modulespath => $hdp-hadoop::params::conf_dir,
       modulespath => $hdp-hadoop::params::conf_dir,
       filename => 'mapred-queue-acls.xml',
       filename => 'mapred-queue-acls.xml',
       module => 'hdp-hadoop',
       module => 'hdp-hadoop',
-      configuration => $configuration['mapred-queue-acls']
+      configuration => $configuration['mapred-queue-acls'],
+      owner => $hdp-hadoop::params::mapred_user,
+      group => $hdp::params::hadoop_user_group
+    }
+  } else { # Manually overriding ownership of file installed by hadoop package
+    file { "${hdp-hadoop::params::conf_dir}/mapred-queue-acls.xml":
+      owner => $hdp-hadoop::params::mapred_user,
+      group => $hdp::params::hadoop_user_group
     }
     }
   }
   }
   
   
@@ -57,7 +64,9 @@ debug('##Configs generation for hdp-hadoop')
       modulespath => $hdp-hadoop::params::conf_dir,
       modulespath => $hdp-hadoop::params::conf_dir,
       filename => 'hadoop-policy.xml',
       filename => 'hadoop-policy.xml',
       module => 'hdp-hadoop',
       module => 'hdp-hadoop',
-      configuration => $configuration['hadoop-policy']
+      configuration => $configuration['hadoop-policy'],
+      owner => $hdp-hadoop::params::hdfs_user,
+      group => $hdp::params::hadoop_user_group
     }
     }
   }
   }
 
 
@@ -66,7 +75,9 @@ debug('##Configs generation for hdp-hadoop')
         modulespath => $hdp-hadoop::params::conf_dir,
         modulespath => $hdp-hadoop::params::conf_dir,
         filename => 'core-site.xml',
         filename => 'core-site.xml',
         module => 'hdp-hadoop',
         module => 'hdp-hadoop',
-        configuration => $configuration['core-site']
+        configuration => $configuration['core-site'],
+        owner => $hdp-hadoop::params::hdfs_user,
+        group => $hdp::params::hadoop_user_group
       }
       }
     }
     }
 
 
@@ -75,7 +86,9 @@ debug('##Configs generation for hdp-hadoop')
       modulespath => $hdp-hadoop::params::conf_dir,
       modulespath => $hdp-hadoop::params::conf_dir,
       filename => 'mapred-site.xml',
       filename => 'mapred-site.xml',
       module => 'hdp-hadoop',
       module => 'hdp-hadoop',
-      configuration => $configuration['mapred-site']
+      configuration => $configuration['mapred-site'],
+      owner => $hdp-hadoop::params::mapred_user,
+      group => $hdp::params::hadoop_user_group
     }
     }
   }
   }
   
   
@@ -84,7 +97,9 @@ debug('##Configs generation for hdp-hadoop')
       modulespath => $hdp-hadoop::params::conf_dir,
       modulespath => $hdp-hadoop::params::conf_dir,
       filename => 'capacity-scheduler.xml',
       filename => 'capacity-scheduler.xml',
       module => 'hdp-hadoop',
       module => 'hdp-hadoop',
-      configuration => $configuration['capacity-scheduler']
+      configuration => $configuration['capacity-scheduler'],
+      owner => $hdp-hadoop::params::hdfs_user,
+      group => $hdp::params::hadoop_user_group
     }
     }
   }
   }
 
 
@@ -93,7 +108,9 @@ debug('##Configs generation for hdp-hadoop')
       modulespath => $hdp-hadoop::params::conf_dir,
       modulespath => $hdp-hadoop::params::conf_dir,
       filename => 'hdfs-site.xml',
       filename => 'hdfs-site.xml',
       module => 'hdp-hadoop',
       module => 'hdp-hadoop',
-      configuration => $configuration['hdfs-site']
+      configuration => $configuration['hdfs-site'],
+      owner => $hdp-hadoop::params::hdfs_user,
+      group => $hdp::params::hadoop_user_group
     }
     }
   }
   }
 
 

+ 2 - 2
ambari-agent/src/main/puppet/modules/hdp-hadoop/manifests/params.pp

@@ -120,7 +120,7 @@ class hdp-hadoop::params(
 
 
   $dfs_support_append = hdp_default("hadoop/hdfs-site/dfs_support_append",true)
   $dfs_support_append = hdp_default("hadoop/hdfs-site/dfs_support_append",true)
 
 
-  $dfs_webhdfs_enabled = hdp_default("hadoop/hdfs-site/dfs_webhdfs_enabled","false")
+  $dfs_webhdfs_enabled = hdp_default("hadoop/hdfs-site/dfs_webhdfs_enabled",false)
 
 
 
 
  ######### mapred #######
  ######### mapred #######
@@ -171,7 +171,7 @@ class hdp-hadoop::params(
   $task_bin_exe = hdp_default("hadoop/health_check/task_bin_exe")
   $task_bin_exe = hdp_default("hadoop/health_check/task_bin_exe")
 
 
   $rca_enabled = hdp_default("rca_enabled", false)
   $rca_enabled = hdp_default("rca_enabled", false)
-  if ($rca_enabled == true or $rca_enabled == "true") {
+  if ($rca_enabled == true) {
     $rca_prefix = ""
     $rca_prefix = ""
   } else {
   } else {
     $rca_prefix = "###"
     $rca_prefix = "###"

+ 1 - 1
ambari-agent/src/main/puppet/modules/hdp-hbase/manifests/params.pp

@@ -47,7 +47,7 @@ class hdp-hbase::params() inherits hdp::params
   #TODO: check if any of these 'hdfs' vars need to be euated with vars in hdp-hadoop
   #TODO: check if any of these 'hdfs' vars need to be euated with vars in hdp-hadoop
   $hdfs_enable_shortcircuit_read = hdp_default("hadoop/hbase-site/hdfs_enable_shortcircuit_read",true)
   $hdfs_enable_shortcircuit_read = hdp_default("hadoop/hbase-site/hdfs_enable_shortcircuit_read",true)
 
 
-  $hdfs_enable_shortcircuit_skipchecksum = hdp_default("hadoop/hbase-site/hdfs_enable_shortcircuit_skipchecksum","false")
+  $hdfs_enable_shortcircuit_skipchecksum = hdp_default("hadoop/hbase-site/hdfs_enable_shortcircuit_skipchecksum",false)
 
 
   $hdfs_support_append = hdp_default("hadoop/hbase-site/hdfs_support_append",true)
   $hdfs_support_append = hdp_default("hadoop/hbase-site/hdfs_support_append",true)
 
 

+ 1 - 1
ambari-agent/src/main/puppet/modules/hdp-hcat-old/manifests/params.pp

@@ -47,7 +47,7 @@ class hdp-hcat::params() inherits hdp::params
 
 
   $hcat_metastore_principal = hdp_default("hadoop/hive-site/hcat_metastore_principal")
   $hcat_metastore_principal = hdp_default("hadoop/hive-site/hcat_metastore_principal")
 
 
-  $hcat_metastore_sasl_enabled = hdp_default("hadoop/hive-site/hcat_metastore_sasl_enabled","false")
+  $hcat_metastore_sasl_enabled = hdp_default("hadoop/hive-site/hcat_metastore_sasl_enabled",false)
 
 
   #TODO: using instead hcat_server_host in hdp::params $hcat_metastore_server_host = hdp_default("hadoop/hive-site/hcat_metastore_server_host")
   #TODO: using instead hcat_server_host in hdp::params $hcat_metastore_server_host = hdp_default("hadoop/hive-site/hcat_metastore_server_host")
 
 

+ 1 - 1
ambari-agent/src/main/puppet/modules/hdp-hive/files/startHiveserver2.sh

@@ -18,5 +18,5 @@
 # under the License.
 # under the License.
 #
 #
 #
 #
-/usr/lib/hive/bin/hiveserver2 > $1 2> $2 &
+/usr/lib/hive/bin/hiveserver2 -hiveconf hive.metastore.uris=' ' > $1 2> $2 &
 echo $!|cat>$3
 echo $!|cat>$3

+ 24 - 21
ambari-agent/src/main/puppet/modules/hdp-hive/manifests/hive/service_check.pp

@@ -48,30 +48,33 @@ class hdp-hive::hive::service_check() inherits hdp-hive::params
     user => $smoke_test_user
     user => $smoke_test_user
   }
   }
 
 
-  $unique = hdp_unique_id_and_date()
-  $output_file = "/apps/hive/warehouse/hivesmoke${unique}"
-  $test_cmd = "fs -test -e ${output_file}"
+#  $unique = hdp_unique_id_and_date()
+#  $output_file = "/apps/hive/warehouse/hivesmoke${unique}"
+#  $test_cmd = "fs -test -e ${output_file}"
 
 
-  file { '/tmp/hiveSmoke.sh':
-    ensure => present,
-    source => "puppet:///modules/hdp-hive/hiveSmoke.sh",
-    mode => '0755',
-  }
+#  file { '/tmp/hiveSmoke.sh':
+#    ensure => present,
+#    source => "puppet:///modules/hdp-hive/hiveSmoke.sh",
+#    mode => '0755',
+#  }
+#
+#  exec { '/tmp/hiveSmoke.sh':
+#    command => "su - ${smoke_test_user} -c 'env JAVA_HOME=$hdp::params::java64_home sh /tmp/hiveSmoke.sh hivesmoke${unique}'",
+#    tries => 3,
+#    try_sleep => 5,
+#    path => '/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
+#    notify => Hdp-hadoop::Exec-hadoop['hive::service_check::test'],
+#    logoutput => "true"
+#  }
 
 
-  exec { '/tmp/hiveSmoke.sh':
-    command => "su - ${smoke_test_user} -c 'env JAVA_HOME=$hdp::params::java64_home sh /tmp/hiveSmoke.sh hivesmoke${unique}'",
-    tries => 3,
-    try_sleep => 5,
-    path => '/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin',
-    notify => Hdp-hadoop::Exec-hadoop['hive::service_check::test'],
-    logoutput => "true"
-  }
+#  hdp-hadoop::exec-hadoop { 'hive::service_check::test':
+#    command => $test_cmd,
+#    refreshonly => true
+#  }
 
 
-  hdp-hadoop::exec-hadoop { 'hive::service_check::test':
-    command => $test_cmd,
-    refreshonly => true
-  }
+#  File[$smoke_test_path] -> File[$smoke_test_sql] -> Exec[$smoke_test_path] -> File['/tmp/hiveSmoke.sh'] -> Exec['/tmp/hiveSmoke.sh'] -> Hdp-Hadoop::Exec-Hadoop['hive::service_check::test']
 
 
-  File[$smoke_test_path] -> File[$smoke_test_sql] -> Exec[$smoke_test_path] -> File['/tmp/hiveSmoke.sh'] -> Exec['/tmp/hiveSmoke.sh'] -> Hdp-Hadoop::Exec-Hadoop['hive::service_check::test']
+  include hdp-hcat::hcat::service_check  
 
 
+  File[$smoke_test_path] -> File[$smoke_test_sql] -> Exec[$smoke_test_path]
 }
 }

+ 3 - 3
ambari-agent/src/main/puppet/modules/hdp-hive/manifests/params.pp

@@ -32,7 +32,7 @@ class hdp-hive::params() inherits hdp::params
   $hive_metastore_port = hdp_default("hive_metastore_port",9083)
   $hive_metastore_port = hdp_default("hive_metastore_port",9083)
   $hive_lib = hdp_default("hive_lib","/usr/lib/hive/lib/") #TODO: should I remove and just use hive_dbroot
   $hive_lib = hdp_default("hive_lib","/usr/lib/hive/lib/") #TODO: should I remove and just use hive_dbroot
   $hive_var_lib = hdp_default("hive_var_lib","/var/lib/hive")  
   $hive_var_lib = hdp_default("hive_var_lib","/var/lib/hive")  
-  $hive_url = 'jdbc:hive2://localhost:10000'
+  $hive_url = "jdbc:hive2://${hive_server_host}:10000"
 
 
   ### hive-env
   ### hive-env
   $hive_conf_dir = $hdp::params::hive_conf_dir
   $hive_conf_dir = $hdp::params::hive_conf_dir
@@ -49,9 +49,9 @@ class hdp-hive::params() inherits hdp::params
   $hive_database_name = hdp_default("hadoop/hive-site/hive_database_name","hive")
   $hive_database_name = hdp_default("hadoop/hive-site/hive_database_name","hive")
 
 
   if ($hdp::params::security_enabled == true) {
   if ($hdp::params::security_enabled == true) {
-    $hive_metastore_sasl_enabled = "true"
+    $hive_metastore_sasl_enabled = true
   } else {
   } else {
-    $hive_metastore_sasl_enabled = "false"
+    $hive_metastore_sasl_enabled = false
   }
   }
 
 
   $keytab_path = hdp_default("keytab_path","/etc/security/keytabs")
   $keytab_path = hdp_default("keytab_path","/etc/security/keytabs")

+ 6 - 4
ambari-agent/src/main/puppet/modules/hdp-mysql/files/startMysql.sh

@@ -24,7 +24,9 @@ mysqldbuser=$1
 mysqldbpasswd=$2
 mysqldbpasswd=$2
 mysqldbhost=$3
 mysqldbhost=$3
 
 
-echo "Adding user $mysqldbuser@$mysqldbhost"
-echo "CREATE USER '$mysqldbuser'@'$mysqldbhost' IDENTIFIED BY '$mysqldbpasswd';" > mysql -u root
-echo "GRANT ALL PRIVILEGES ON *.* TO '$mysqldbuser'@'$mysqldbhost';" > mysql -u root
-echo "flush privileges;" > mysql -u root
+echo "Adding user $mysqldbuser@$mysqldbhost and $mysqldbuser@localhost"
+mysql -u root -e "CREATE USER '$mysqldbuser'@'$mysqldbhost' IDENTIFIED BY '$mysqldbpasswd';"
+mysql -u root -e "CREATE USER '$mysqldbuser'@'localhost' IDENTIFIED BY '$mysqldbpasswd';"
+mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO '$mysqldbuser'@'$mysqldbhost';"
+mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO '$mysqldbuser'@'localhost';"
+mysql -u root -e "flush privileges;"

+ 3 - 1
ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/params.pp

@@ -27,6 +27,7 @@ class hdp-nagios::params() inherits hdp::params
   $conf_dir = hdp_default("nagios_conf_dir","/etc/nagios")
   $conf_dir = hdp_default("nagios_conf_dir","/etc/nagios")
 
 
   $plugins_dir = "/usr/lib64/nagios/plugins"
   $plugins_dir = "/usr/lib64/nagios/plugins"
+  $eventhandlers_dir = "/usr/lib64/nagios/eventhandlers"  # Does not exist yet
   $nagios_pid_dir = "/var/run/nagios"
   $nagios_pid_dir = "/var/run/nagios"
 
 
   $nagios_obj_dir = hdp_default("nagios_obj_dir","/etc/nagios/objects")
   $nagios_obj_dir = hdp_default("nagios_obj_dir","/etc/nagios/objects")
@@ -37,7 +38,8 @@ class hdp-nagios::params() inherits hdp::params
   $nagios_servicegroup_cfg = hdp_default("nagios_servicegroup_cfg","${nagios_obj_dir}/hadoop-servicegroups.cfg")
   $nagios_servicegroup_cfg = hdp_default("nagios_servicegroup_cfg","${nagios_obj_dir}/hadoop-servicegroups.cfg")
   $nagios_service_cfg = hdp_default("nagios_service_cfg","${nagios_obj_dir}/hadoop-services.cfg")
   $nagios_service_cfg = hdp_default("nagios_service_cfg","${nagios_obj_dir}/hadoop-services.cfg")
   $nagios_command_cfg = hdp_default("nagios_command_cfg","${nagios_obj_dir}/hadoop-commands.cfg")
   $nagios_command_cfg = hdp_default("nagios_command_cfg","${nagios_obj_dir}/hadoop-commands.cfg")
-  
+  $nagios_resource_cfg = hdp_default("nagios_resource_cfg","${conf_dir}/resource.cfg")
+
   $nagios_web_login = hdp_default("nagios_web_login","nagiosadmin")
   $nagios_web_login = hdp_default("nagios_web_login","nagiosadmin")
   $nagios_web_password = hdp_default("nagios_web_password","admin")
   $nagios_web_password = hdp_default("nagios_web_password","admin")
   
   

+ 7 - 4
ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server.pp

@@ -98,7 +98,7 @@ class hdp-nagios::server(
      Class['hdp-nagios::server::packages'] -> Exec['rm -f /var/nagios/rw/nagios.cmd'] -> Hdp::Directory[$nagios_config_dir] -> Hdp::Directory[$plugins_dir] -> Hdp::Directory[$nagios_obj_dir] ->  Hdp::Directory_recursive_create[$nagios_pid_dir] -> Hdp::Directory[$nagios_var_dir]
      Class['hdp-nagios::server::packages'] -> Exec['rm -f /var/nagios/rw/nagios.cmd'] -> Hdp::Directory[$nagios_config_dir] -> Hdp::Directory[$plugins_dir] -> Hdp::Directory[$nagios_obj_dir] ->  Hdp::Directory_recursive_create[$nagios_pid_dir] -> Hdp::Directory[$nagios_var_dir]
 
 
   } elsif ($service_state in ['running','stopped','installed_and_configured']) {
   } elsif ($service_state in ['running','stopped','installed_and_configured']) {
-    class { 'hdp-nagios::server::packages' : }
+    class { 'hdp-nagios::server::packages' : service_state => $service_state}
 
 
     hdp::directory { $nagios_config_dir:
     hdp::directory { $nagios_config_dir:
       service_state => $service_state,
       service_state => $service_state,
@@ -114,7 +114,7 @@ class hdp-nagios::server(
       service_state => $service_state,
       service_state => $service_state,
       force => true
       force => true
     }
     }
-	
+
 	hdp::directory_recursive_create { $nagios_pid_dir:
 	hdp::directory_recursive_create { $nagios_pid_dir:
       service_state => $service_state,
       service_state => $service_state,
       owner => $nagios_user,
       owner => $nagios_user,
@@ -146,10 +146,13 @@ class hdp-nagios::server(
       group => $hdp-nagios::params::nagios_group
       group => $hdp-nagios::params::nagios_group
     }
     }
 	
 	
-   if ($service_state == 'installed_and_configured') {
+    if ($service_state == 'installed_and_configured') {
       $webserver_state = 'restart'
       $webserver_state = 'restart'
+    } elsif ($service_state == 'running') {
+      $webserver_state = 'running'
     } else {
     } else {
-      $webserver_state = $service_state
+      # We are never stopping httpd
+      #$webserver_state = $service_state
     }
     }
 
 
     class { 'hdp-monitor-webserver': service_state => $webserver_state}
     class { 'hdp-monitor-webserver': service_state => $webserver_state}

+ 1 - 0
ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server/config.pp

@@ -24,6 +24,7 @@ class hdp-nagios::server::config()
   $host_cfg = $hdp-nagios::params::nagios_host_cfg
   $host_cfg = $hdp-nagios::params::nagios_host_cfg
   
   
   hdp-nagios::server::configfile { 'nagios.cfg': conf_dir => $hdp-nagios::params::conf_dir }
   hdp-nagios::server::configfile { 'nagios.cfg': conf_dir => $hdp-nagios::params::conf_dir }
+  hdp-nagios::server::configfile { 'resource.cfg': conf_dir => $hdp-nagios::params::conf_dir }
   hdp-nagios::server::configfile { 'hadoop-hosts.cfg': }
   hdp-nagios::server::configfile { 'hadoop-hosts.cfg': }
   hdp-nagios::server::configfile { 'hadoop-hostgroups.cfg': }
   hdp-nagios::server::configfile { 'hadoop-hostgroups.cfg': }
   hdp-nagios::server::configfile { 'hadoop-servicegroups.cfg': }
   hdp-nagios::server::configfile { 'hadoop-servicegroups.cfg': }

+ 46 - 10
ambari-agent/src/main/puppet/modules/hdp-nagios/manifests/server/packages.pp

@@ -28,17 +28,53 @@ class hdp-nagios::server::packages(
       ensure => 'uninstalled'
       ensure => 'uninstalled'
     }
     }
   } elsif ($service_state in ['running','stopped','installed_and_configured']) {
   } elsif ($service_state in ['running','stopped','installed_and_configured']) {
-        hdp-nagios::server::package { ['nagios-server','nagios-fping','nagios-plugins','nagios-addons','nagios-php-pecl-json']:
-          ensure => 'present'
-    }
-  } 
-  Hdp-nagios::Server::Package['nagios-server'] -> Hdp::Package['nagios-plugins'] #other order produces package conflict
-  Hdp-nagios::Server::Package['nagios-plugins'] -> Hdp::Package['nagios-addons'] #other order produces package conflict
+  
+
+  
+  if ($service_state == 'installed_and_configured') {
+    package{'nagios-plugins-process-old':
+      name   => 'nagios-plugins',
+      ensure => absent}
+  }
+	
+  hdp::package { 'nagios-server': 
+    ensure      => present,
+    java_needed => false
+  }
+  
+  hdp::package { 'nagios-fping': 
+    ensure      => present,
+    java_needed => false
+  }
+  
+  hdp::package { 'nagios-addons': 
+    ensure      => present,
+    java_needed => false
+  }
+	
+  hdp::package { 'nagios-plugins': 
+    ensure      => present,
+    java_needed => false
+  }
+  
+  hdp::package { 'nagios-php-pecl-json': 
+    ensure      => present,
+    java_needed => false
+  }
+  
+  
+debug("## state: $service_state")
+  if ($service_state == 'installed_and_configured') {
+    debug("##Adding removing dep")
+    Package['nagios-plugins-process-old'] -> Hdp::Package['nagios-plugins']
+  }
+
+  Hdp::Package['nagios-plugins'] -> Hdp::Package['nagios-server'] -> Hdp::Package['nagios-fping'] -> Hdp::Package['nagios-addons'] -> Hdp::Package['nagios-php-pecl-json']
+
+    
+
+} 
 
 
-  anchor{'hdp-nagios::server::packages::begin':} -> Hdp-nagios::Server::Package<||> -> anchor{'hdp-nagios::server::packages::end':}
-  Anchor['hdp-nagios::server::packages::begin'] -> Hdp::Package['nagios-server'] ->
-      Hdp::Package['nagios-addons'] -> Anchor['hdp-nagios::server::packages::end']
-  Hdp-nagios::Server::Package['nagios-fping'] -> Hdp-nagios::Server::Package['nagios-plugins']
 }
 }
 
 
 
 

+ 3 - 3
ambari-agent/src/main/puppet/modules/hdp-nagios/templates/hadoop-services.cfg.erb

@@ -422,7 +422,7 @@ define service {
         use                     hadoop-service
         use                     hadoop-service
         service_description     HIVE-METASTORE::HIVE-METASTORE status check
         service_description     HIVE-METASTORE::HIVE-METASTORE status check
         servicegroups           HIVE-METASTORE
         servicegroups           HIVE-METASTORE
-        <%if scope.function_hdp_template_var("security_enabled") == "true"-%>
+        <%if scope.function_hdp_template_var("security_enabled")-%>
         check_command           check_hive_metastore_status!9083!<%=scope.function_hdp_template_var("java64_home")%>!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         check_command           check_hive_metastore_status!9083!<%=scope.function_hdp_template_var("java64_home")%>!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         <%else-%>
         <%else-%>
         check_command           check_hive_metastore_status!9083!<%=scope.function_hdp_template_var("java64_home")%>!false
         check_command           check_hive_metastore_status!9083!<%=scope.function_hdp_template_var("java64_home")%>!false
@@ -439,7 +439,7 @@ define service {
         use                     hadoop-service
         use                     hadoop-service
         service_description     OOZIE::Oozie status check
         service_description     OOZIE::Oozie status check
         servicegroups           OOZIE
         servicegroups           OOZIE
-        <%if scope.function_hdp_template_var("security_enabled") == "true" -%>
+        <%if scope.function_hdp_template_var("security_enabled")-%>
         check_command           check_oozie_status!11000!<%=scope.function_hdp_template_var("java64_home")%>!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         check_command           check_oozie_status!11000!<%=scope.function_hdp_template_var("java64_home")%>!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         <%else-%>
         <%else-%>
         check_command           check_oozie_status!11000!<%=scope.function_hdp_template_var("java64_home")%>!false
         check_command           check_oozie_status!11000!<%=scope.function_hdp_template_var("java64_home")%>!false
@@ -456,7 +456,7 @@ define service {
         use                     hadoop-service
         use                     hadoop-service
         service_description     TEMPLETON::Templeton status check
         service_description     TEMPLETON::Templeton status check
         servicegroups           TEMPLETON
         servicegroups           TEMPLETON
-        <%if scope.function_hdp_template_var("security_enabled") == "true"-%>
+        <%if scope.function_hdp_template_var("security_enabled")-%>
         check_command           check_templeton_status!50111!v1!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         check_command           check_templeton_status!50111!v1!true!<%=scope.function_hdp_template_var("keytab_path")%>/<%=scope.function_hdp_template_var("nagios_user")%>.headless.keytab!<%=scope.function_hdp_template_var("nagios_user")%>
         <%else-%>
         <%else-%>
         check_command           check_templeton_status!50111!v1!false
         check_command           check_templeton_status!50111!v1!false

+ 1 - 1
ambari-agent/src/main/puppet/modules/hdp-nagios/templates/nagios.cfg.erb

@@ -120,7 +120,7 @@ precached_object_file=/var/nagios/objects.precache
 # defined as macros in this file and restrictive permissions (600)
 # defined as macros in this file and restrictive permissions (600)
 # can be placed on this file.
 # can be placed on this file.
 
 
-resource_file=/etc/nagios/resource.cfg
+resource_file=<%=scope.function_hdp_template_var("nagios_resource_cfg")%>
 
 
 
 
 
 

+ 33 - 0
ambari-agent/src/main/puppet/modules/hdp-nagios/templates/resource.cfg.erb

@@ -0,0 +1,33 @@
+###########################################################################
+#
+# RESOURCE.CFG - Sample Resource File for Nagios 3.2.3
+#
+# Last Modified: 09-10-2003
+#
+# You can define $USERx$ macros in this file, which can in turn be used
+# in command definitions in your host config file(s).  $USERx$ macros are
+# useful for storing sensitive information such as usernames, passwords,
+# etc.  They are also handy for specifying the path to plugins and
+# event handlers - if you decide to move the plugins or event handlers to
+# a different directory in the future, you can just update one or two
+# $USERx$ macros, instead of modifying a lot of command definitions.
+#
+# The CGIs will not attempt to read the contents of resource files, so
+# you can set restrictive permissions (600 or 660) on them.
+#
+# Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$)
+#
+# Resource files may also be used to store configuration directives for
+# external data sources like MySQL...
+#
+###########################################################################
+
+# Sets $USER1$ to be the path to the plugins
+$USER1$=<%=scope.function_hdp_template_var("plugins_dir")%>
+
+# Sets $USER2$ to be the path to event handlers
+#$USER2$=<%=scope.function_hdp_template_var("eventhandlers_dir")%>
+
+# Store some usernames and passwords (hidden from the CGIs)
+#$USER3$=someuser
+#$USER4$=somepassword

+ 1 - 1
ambari-agent/src/main/puppet/modules/hdp-oozie/manifests/service.pp

@@ -34,7 +34,7 @@ class hdp-oozie::service(
   $jar_location = $hdp::params::hadoop_jar_location
   $jar_location = $hdp::params::hadoop_jar_location
   $ext_js_path = "/usr/share/HDP-oozie/ext.zip"
   $ext_js_path = "/usr/share/HDP-oozie/ext.zip"
   
   
-  if ($lzo_enabled) {
+  if ($lzo_enabled == true) {
     $lzo_jar_suffix = "-jars /usr/lib/hadoop/lib/hadoop-lzo-0.5.0.jar"
     $lzo_jar_suffix = "-jars /usr/lib/hadoop/lib/hadoop-lzo-0.5.0.jar"
   } else {
   } else {
     $lzo_jar_suffix = ""
     $lzo_jar_suffix = ""

+ 2 - 2
ambari-agent/src/main/puppet/modules/hdp-templeton/manifests/params.pp

@@ -45,14 +45,14 @@ class hdp-templeton::params() inherits hdp::params
   
   
   ### templeton-site
   ### templeton-site
   $hadoop_conf_dir = hdp_default("hadoop/templeton-site/hadoop_conf_dir")
   $hadoop_conf_dir = hdp_default("hadoop/templeton-site/hadoop_conf_dir")
-  $templeton_jar = hdp_default("hadoop/templeton-site/templeton_jar","/usr/share/templeton/templeton-0.1.4.14.jar")
+  $templeton_jar = hdp_default("hadoop/templeton-site/templeton_jar","/usr/lib/hcatalog/share/webhcat/svr/webhcat.jar")
   $zookeeper_jar = hdp_default("hadoop/templeton-site/zookeeper_jar","/usr/lib/zookeeper/zookeeper.jar")
   $zookeeper_jar = hdp_default("hadoop/templeton-site/zookeeper_jar","/usr/lib/zookeeper/zookeeper.jar")
   $pig_tar_gz = hdp_default("hadoop/templeton-site/pig_tar_gz","$dest_pig_tar_name")
   $pig_tar_gz = hdp_default("hadoop/templeton-site/pig_tar_gz","$dest_pig_tar_name")
   $pig_tar_name_hdfs = hdp_default("hadoop/templeton-site/pig_tar_name_hdfs","pig-0.9.2.14")
   $pig_tar_name_hdfs = hdp_default("hadoop/templeton-site/pig_tar_name_hdfs","pig-0.9.2.14")
 
 
   $hive_tar_gz = hdp_default("hadoop/templeton-site/hive_tar_gz","$dest_hive_tar_name")
   $hive_tar_gz = hdp_default("hadoop/templeton-site/hive_tar_gz","$dest_hive_tar_name")
   $hive_tar_gz_name = hdp_default("hadoop/templeton-site/hive_tar_gz_name","hive-0.9.0.14")
   $hive_tar_gz_name = hdp_default("hadoop/templeton-site/hive_tar_gz_name","hive-0.9.0.14")
-  $hive_metastore_sasl_enabled = hdp_default("hadoop/templeton-site/hive_metastore_sasl_enabled","no")
+  $hive_metastore_sasl_enabled = hdp_default("hadoop/templeton-site/hive_metastore_sasl_enabled",false)
 
 
   $templeton_metastore_principal = hdp_default("hadoop/templeton-site/templeton_metastore_principal")
   $templeton_metastore_principal = hdp_default("hadoop/templeton-site/templeton_metastore_principal")
 
 

+ 9 - 1
ambari-agent/src/main/puppet/modules/hdp/lib/puppet/parser/functions/hdp_default.rb

@@ -25,7 +25,15 @@ module Puppet::Parser::Functions
     var_name = scoped_var_name.split("/").last
     var_name = scoped_var_name.split("/").last
     default = args[1]
     default = args[1]
     val = lookupvar("::#{var_name}")
     val = lookupvar("::#{var_name}")
-    function_hdp_is_empty(val) ? (default||"") : val
+    # To workaround string-boolean comparison issues,
+    # ensure that we return boolean result if the default value
+    # is also boolean
+    if default == true or default == false # we expect boolean value as a result
+      casted_val = (val == "true" or val == true) # converting to boolean
+    else # default
+      casted_val = val
+    end
+    function_hdp_is_empty(val) ? (default||"") : casted_val
   end
   end
 end
 end
 
 

+ 31 - 1
ambari-agent/src/main/puppet/modules/hdp/manifests/params.pp

@@ -305,6 +305,16 @@ class hdp::params()
     rrdtool-python => {
     rrdtool-python => {
       64 => ['python-rrdtool.x86_64']
       64 => ['python-rrdtool.x86_64']
     },
     },
+    # The 32bit version of package rrdtool is removed on centos 5/6 to prevent conflict ( BUG-2408)
+    rrdtool => {
+          64 => {
+            'ALL' => 'rrdtool.i686',
+            'centos6' => 'rrdtool.i686',
+            'centos5' => 'rrdtool.i386',
+            'redhat6' => 'rrdtool.i686',
+            'redhat5' => 'rrdtool.i386'
+            }
+    },
     ambari-log4j => {
     ambari-log4j => {
       64 => ['ambari-log4j']
       64 => ['ambari-log4j']
     } 
     } 
@@ -393,6 +403,7 @@ class hdp::params()
      suse => 'htpasswd2'} 
      suse => 'htpasswd2'} 
 
 
     }
     }
+    
 
 
     $alt_package_names = 
     $alt_package_names = 
 {
 {
@@ -511,6 +522,18 @@ class hdp::params()
     rrdtool-python => {
     rrdtool-python => {
       64 => {'ALL' =>'python-rrdtool.x86_64'}
       64 => {'ALL' =>'python-rrdtool.x86_64'}
     },
     },
+
+    # The 32bit version of package rrdtool is removed on centos 5/6 to prevent conflict ( BUG-2408)
+    rrdtool => {
+      64 => {
+        'ALL' => 'rrdtool.i686',
+        'centos6' => 'rrdtool.i686',
+        'centos5' => 'rrdtool.i386',
+        'redhat6' => 'rrdtool.i686',
+        'redhat5' => 'rrdtool.i386'
+        }
+    },
+
     ambari-log4j => {
     ambari-log4j => {
       64 => {'ALL' =>'ambari-log4j'}
       64 => {'ALL' =>'ambari-log4j'}
     },
     },
@@ -531,7 +554,14 @@ class hdp::params()
     redhat5 => '/etc/yum.repos.d'
     redhat5 => '/etc/yum.repos.d'
   }
   }
 
 
-  $rrd_py_path = '/var/www/cgi-bin'
+  $rrd_py_path =
+  {
+    suse => '/srv/www/cgi-bin',
+    centos6 => '/var/www/cgi-bin',
+    centos5 => '/var/www/cgi-bin',
+    redhat6 => '/var/www/cgi-bin',
+    redhat5 => '/var/www/cgi-bin'
+  }
 
 
 
 
 
 

+ 2 - 2
ambari-agent/src/main/python/ambari_agent/AmbariConfig.py

@@ -28,8 +28,8 @@ content = """
 
 
 [server]
 [server]
 hostname=localhost
 hostname=localhost
-url_port=4080
-secured_url_port=8443
+url_port=8440
+secured_url_port=8441
 
 
 [agent]
 [agent]
 prefix=/tmp/ambari-agent
 prefix=/tmp/ambari-agent

+ 15 - 0
ambari-agent/src/main/python/ambari_agent/Grep.py

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

+ 16 - 6
ambari-agent/src/main/python/ambari_agent/Hardware.py

@@ -60,8 +60,8 @@ class Hardware:
                      'mountpoint' : mountpoint,
                      'mountpoint' : mountpoint,
                      'type': type,
                      'type': type,
                      'device' : device }
                      'device' : device }
-
-        mounts.append(mountinfo)
+        if os.access(mountpoint, os.W_OK):
+          mounts.append(mountinfo)
         pass
         pass
       pass
       pass
     return mounts
     return mounts
@@ -104,8 +104,18 @@ class Hardware:
           value = keyValue[1].strip()
           value = keyValue[1].strip()
           """Convert to KB"""
           """Convert to KB"""
           parts = value.split()
           parts = value.split()
-          #TODO need better parsing for detecting KB/GB
-          mem_in_kb = long(float(parts[0]) * 1024 * 1024);
+          if len(parts) == 2:
+            mem_size = parts[1].upper()
+            if mem_size in ["GB", "G"]:
+              mem_in_kb = long(float(parts[0]) * 1024 * 1024)
+            elif mem_size in ["MB", "M"]:
+              mem_in_kb = long(float(parts[0]) * 1024)
+            elif mem_size in ["KB", "K"]:
+              mem_in_kb = long(float(parts[0]))
+            else:
+              mem_in_kb = long(float(parts[0]) / 1024)
+          else:
+            mem_in_kb = long(float(parts[0]) / 1024)
           retDict[strippedKey] = mem_in_kb
           retDict[strippedKey] = mem_in_kb
           pass
           pass
         else:
         else:
@@ -122,7 +132,7 @@ class Hardware:
       pass
       pass
     
     
     logger.info("Facter info : \n" + pprint.pformat(retDict))
     logger.info("Facter info : \n" + pprint.pformat(retDict))
-    return retDict
+    return retDict  
   
   
   def facterInfo(self):   
   def facterInfo(self):   
     facterHome = AmbariConfig.config.get("puppet", "facter_home")
     facterHome = AmbariConfig.config.get("puppet", "facter_home")
@@ -154,7 +164,7 @@ class Hardware:
         facterInfo = infoDict
         facterInfo = infoDict
         pass
         pass
       else:
       else:
-        pass
+        logger.error("Facter home at " + facterHome + " does not exist")
     except:
     except:
       logger.info("Traceback " + traceback.format_exc())
       logger.info("Traceback " + traceback.format_exc())
       pass
       pass

+ 20 - 2
ambari-agent/src/main/python/ambari_agent/NetUtil.py

@@ -1,3 +1,19 @@
+# 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.
+
+
 from httplib import HTTPS
 from httplib import HTTPS
 from urlparse import urlparse
 from urlparse import urlparse
 import time
 import time
@@ -34,8 +50,10 @@ class NetUtil:
       status = response.status    
       status = response.status    
       logger.info("DEBUG: Calling url received " + str(status))
       logger.info("DEBUG: Calling url received " + str(status))
       
       
-      if status == 200: return True
-      else: return False
+      if status == 200: 
+        return True
+      else: 
+        return False
     except Exception, e:
     except Exception, e:
       logger.info("Failed to connect to " + str(url) + " due to " + str(e))
       logger.info("Failed to connect to " + str(url) + " due to " + str(e))
       return False
       return False

+ 60 - 0
ambari-agent/src/main/python/ambari_agent/machine.py

@@ -0,0 +1,60 @@
+#!/usr/bin/env python2.6
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+import sys
+import subprocess
+
+# please keep compatible with Python 2.4 or greater
+def doExec(key, command, preLF=False):
+  try:
+    osStat = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out, err = osStat.communicate()
+    if 0 != osStat.returncode or 0 == len(out.strip()):
+      print "%s: UNAVAILABLE" % (key)
+    else:
+      if (preLF):
+        print "%s: ok\n %s" % (key, out.strip())
+      else:
+        print "%s: ok %s" % (key, out.strip())
+  except:
+    print "%s: UNAVAILABLE" % (key)
+  
+def main(argv=None):
+  doExec('hostname', ["hostname", "-f"])
+  doExec('ip', ["hostname", "-i"])
+  doExec('cpu', ["sh", "-c", "cat /proc/cpuinfo | grep 'model name' | awk -F': ' '{ print $2; }'"])
+  doExec('memory', ["sh", "-c", "cat /proc/meminfo | grep MemTotal | awk -F': ' '{ print $2/1024/1024 \" GB\"; }'"])
+  doExec('disks', ["df", "-h"], True)
+  doExec('os', ["sh", "-c", "cat /etc/issue.net | head -1"])
+  doExec('iptables', ["iptables", "-vnL"], True)
+  doExec('selinux', ["sh", "-c", "cat /etc/selinux/config | grep ^SELINUX"])
+
+  for REQ in (["yum", "rpm", "openssl", "curl", "wget", "net-snmp", "net-snmp-utils", "ntpd"]):
+   doExec(REQ, ["rpm", "-qa", REQ])
+
+  for OPT in (["ruby", "puppet", "nagios", "ganglia", "passenger", "hadoop"]):
+   doExec(OPT, ["rpm", "-qa", OPT])
+
+  doExec("yum_repos", ["sh", "-c", "yum -C repolist enabled | egrep \"(AMBARI|HDP)\""], True)
+  # for SUSE-based agents
+  doExec("zypper_repos", ["sh", "-c", "zypper repos | egrep \"(AMBARI|HDP)\""], True)
+
+if __name__ == '__main__':
+  main(sys.argv)

+ 2 - 2
ambari-agent/src/main/python/ambari_agent/main.py

@@ -126,8 +126,8 @@ def main():
   # Check for ambari configuration file.
   # Check for ambari configuration file.
   try:
   try:
     config = AmbariConfig.config
     config = AmbariConfig.config
-    if os.path.exists('/etc/ambari-agent/ambari-agent.ini'):
-      config.read('/etc/ambari-agent/ambari-agent.ini')
+    if os.path.exists('/etc/ambari-agent/conf/ambari-agent.ini'):
+      config.read('/etc/ambari-agent/conf/ambari-agent.ini')
       AmbariConfig.setConfig(config)
       AmbariConfig.setConfig(config)
     else:
     else:
       raise Exception("No config found, use default")
       raise Exception("No config found, use default")

+ 20 - 9
ambari-agent/src/main/python/ambari_agent/manifestGenerator.py

@@ -34,7 +34,7 @@ non_global_configuration_types = ["hdfs-site", "core-site",
                              "hadoop-policy", "mapred-site", 
                              "hadoop-policy", "mapred-site", 
                              "capacity-scheduler", "hbase-site",
                              "capacity-scheduler", "hbase-site",
                              "hbase-policy", "hive-site", "oozie-site", 
                              "hbase-policy", "hive-site", "oozie-site", 
-                             "templeton-site", "hdfs-exclude-file"]
+                             "webhcat-site", "hdfs-exclude-file"]
 
 
 #read static imports from file and write them to manifest
 #read static imports from file and write them to manifest
 def writeImports(outputFile, modulesdir, inputFileName='imports.txt'):
 def writeImports(outputFile, modulesdir, inputFileName='imports.txt'):
@@ -112,7 +112,7 @@ def generateManifest(parsedJson, fileName, modulesdir, ambariconfig):
   #writeHostAttributes(manifest, hostAttributes)
   #writeHostAttributes(manifest, hostAttributes)
 
 
   #writing task definitions 
   #writing task definitions 
-  writeTasks(manifest, roles, ambariconfig)
+  writeTasks(manifest, roles, ambariconfig, clusterHostInfo, hostname)
      
      
   manifest.close()
   manifest.close()
     
     
@@ -130,6 +130,9 @@ def readDict(file, separator='='):
 
 
   #write nodes
   #write nodes
 def writeNodes(outputFile, clusterHostInfo):
 def writeNodes(outputFile, clusterHostInfo):
+  if clusterHostInfo.has_key('zookeeper_hosts'):
+    clusterHostInfo['zookeeper_hosts'] = sorted(clusterHostInfo['zookeeper_hosts'])
+  
   for node in clusterHostInfo.iterkeys():
   for node in clusterHostInfo.iterkeys():
     outputFile.write('$' + node + '= [')
     outputFile.write('$' + node + '= [')
     coma = ''
     coma = ''
@@ -203,7 +206,8 @@ def writeNonGlobalConfigurations(outputFile, xmlConfigs):
   outputFile.write('\n}\n')
   outputFile.write('\n}\n')
 
 
 #write node tasks
 #write node tasks
-def writeTasks(outputFile, roles, ambariconfig):
+def writeTasks(outputFile, roles, ambariconfig, clusterHostInfo=None, 
+               hostname="localhost"):
   #reading dictionaries
   #reading dictionaries
   rolestoclass = "rolesToClass.dict"
   rolestoclass = "rolesToClass.dict"
   if ambariconfig.has_option('puppet','roles_to_class'):
   if ambariconfig.has_option('puppet','roles_to_class'):
@@ -228,13 +232,17 @@ def writeTasks(outputFile, roles, ambariconfig):
 
 
   outputFile.write('class {\'hdp\': stage => ' + str(stageNum) + '}\n')
   outputFile.write('class {\'hdp\': stage => ' + str(stageNum) + '}\n')
   stageNum = stageNum + 1
   stageNum = stageNum + 1
-
+  # Need to hack for zookeeper since we need 
+  zk_hosts = []
   for role in roles :
   for role in roles :
     rolename = role['role']
     rolename = role['role']
     command = role['cmd']
     command = role['cmd']
     taskParams = role['roleParams']
     taskParams = role['roleParams']
     if (rolename == 'ZOOKEEPER_SERVER'):
     if (rolename == 'ZOOKEEPER_SERVER'):
-      taskParams['myid'] = str(get_mac())
+      zk_hosts = clusterHostInfo['zookeeper_hosts']
+      # Sort the list in lexicographical order
+      taskParams['myid'] = str(sorted(zk_hosts).index(hostname) + 1)
+    
     taskParamsNormalized = normalizeTaskParams(taskParams)
     taskParamsNormalized = normalizeTaskParams(taskParams)
     taskParamsPostfix = ''
     taskParamsPostfix = ''
     
     
@@ -245,11 +253,14 @@ def writeTasks(outputFile, roles, ambariconfig):
    
    
     if command in serviceStates:
     if command in serviceStates:
       serviceState = serviceStates[command] 
       serviceState = serviceStates[command] 
-      outputFile.write('class {\'' + className + '\':' + ' stage => ' + str(stageNum) + 
-                     ', service_state => ' + serviceState + taskParamsPostfix + '}\n')
+      outputFile.write('class {\'' + className + '\':' +
+                        ' stage => ' + str(stageNum) + 
+                     ', service_state => ' + serviceState 
+                     + taskParamsPostfix + '}\n')
     else:
     else:
-      outputFile.write('class {\'' + className + '\':' + ' stage => ' + str(stageNum) + 
-                     taskParamsPostfix + '}\n')
+      outputFile.write('class {\'' + className + '\':' + 
+                       ' stage => ' + str(stageNum) + 
+                       taskParamsPostfix + '}\n')
 
 
     stageNum = stageNum + 1
     stageNum = stageNum + 1
   outputFile.write('}\n')
   outputFile.write('}\n')

+ 16 - 2
ambari-agent/src/main/python/ambari_agent/rolesToClass.dict

@@ -1,3 +1,18 @@
+# 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.
+
 NAMENODE = hdp-hadoop::namenode
 NAMENODE = hdp-hadoop::namenode
 DATANODE = hdp-hadoop::datanode
 DATANODE = hdp-hadoop::datanode
 SECONDARY_NAMENODE = hdp-hadoop::snamenode
 SECONDARY_NAMENODE = hdp-hadoop::snamenode
@@ -15,8 +30,7 @@ SQOOP = hdp-sqoop
 OOZIE_SERVER = hdp-oozie::server
 OOZIE_SERVER = hdp-oozie::server
 OOZIE_CLIENT = hdp-oozie::client
 OOZIE_CLIENT = hdp-oozie::client
 HIVE_CLIENT = hdp-hive::client
 HIVE_CLIENT = hdp-hive::client
-HCATALOG_CLIENT = hdp-hcat
-HCATALOG_SERVER = hdp-hcat::server
+HCAT = hdp-hcat
 HIVE_SERVER = hdp-hive::server
 HIVE_SERVER = hdp-hive::server
 HIVE_METASTORE = hdp-hive::metastore
 HIVE_METASTORE = hdp-hive::metastore
 MYSQL_SERVER = hdp-mysql::server
 MYSQL_SERVER = hdp-mysql::server

+ 16 - 0
ambari-agent/src/main/python/ambari_agent/security.py

@@ -1,5 +1,21 @@
 #!/usr/bin/env python2.6
 #!/usr/bin/env python2.6
 
 
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
 import httplib
 import httplib
 import urllib2
 import urllib2
 from urllib2 import Request
 from urllib2 import Request

+ 15 - 0
ambari-agent/src/main/python/ambari_agent/serviceStates.dict

@@ -1,3 +1,18 @@
+# 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.
+
 START = running
 START = running
 INSTALL = installed_and_configured
 INSTALL = installed_and_configured
 STOP = stopped
 STOP = stopped

+ 15 - 0
ambari-agent/src/main/python/ambari_agent/servicesToPidNames.dict

@@ -1,3 +1,18 @@
+# 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.
+
 NAMENODE=hadoop-hdfs-namenode.pid
 NAMENODE=hadoop-hdfs-namenode.pid
 SECONDARY_NAMENODE=hadoop-hdfs-secondarynamenode.pid
 SECONDARY_NAMENODE=hadoop-hdfs-secondarynamenode.pid
 DATANODE=hadoop-hdfs-datanode.pid
 DATANODE=hadoop-hdfs-datanode.pid

+ 1 - 1
ambari-agent/src/test/python/TestActionQueue.py

@@ -43,7 +43,7 @@ class TestActionQueue(TestCase):
   def test_command_in_progress(self):
   def test_command_in_progress(self):
     config = AmbariConfig().getConfig()
     config = AmbariConfig().getConfig()
     tmpfile = tempfile.gettempdir()
     tmpfile = tempfile.gettempdir()
-    config.set('puppet', 'puppetmodules', tmpfile)
+    config.set('agent', 'prefix', tmpfile)
     actionQueue = ActionQueue(config)
     actionQueue = ActionQueue(config)
     actionQueue.IDLE_SLEEP_TIME = 0.01
     actionQueue.IDLE_SLEEP_TIME = 0.01
     executor_started_event = threading.Event()
     executor_started_event = threading.Event()

+ 1 - 1
ambari-agent/src/test/python/TestNetUtil.py

@@ -59,7 +59,7 @@ class TestNetUtil(TestCase):
     self.assertEquals(netutil.checkURL('http://192.168.253.177'), False, "Not reachable IP")
     self.assertEquals(netutil.checkURL('http://192.168.253.177'), False, "Not reachable IP")
     if hasattr(socket, 'setdefaulttimeout'):
     if hasattr(socket, 'setdefaulttimeout'):
       # Set the default timeout on sockets
       # Set the default timeout on sockets
-      socket.setdefaulttimeout(10)
+      socket.setdefaulttimeout(20)
     self.assertEquals(netutil.checkURL('http://www.iana.org/domains/example/'), True, "Good url - HTTP code 200")
     self.assertEquals(netutil.checkURL('http://www.iana.org/domains/example/'), True, "Good url - HTTP code 200")
     self.assertEquals(netutil.checkURL('https://www.iana.org/domains/example/'), True, "Good HTTPS url - HTTP code 200")
     self.assertEquals(netutil.checkURL('https://www.iana.org/domains/example/'), True, "Good HTTPS url - HTTP code 200")
 
 

+ 2 - 2
ambari-project/pom.xml

@@ -17,11 +17,11 @@
   <parent>
   <parent>
     <groupId>org.apache.ambari</groupId>
     <groupId>org.apache.ambari</groupId>
     <artifactId>ambari</artifactId>
     <artifactId>ambari</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
   </parent>
   </parent>
   <groupId>org.apache.ambari</groupId>
   <groupId>org.apache.ambari</groupId>
   <artifactId>ambari-project</artifactId>
   <artifactId>ambari-project</artifactId>
-  <version>1.0.3-SNAPSHOT</version>
+  <version>1.2.0-SNAPSHOT</version>
   <description>Apache Ambari Project POM</description>
   <description>Apache Ambari Project POM</description>
   <name>Apache Ambari Project POM</name>
   <name>Apache Ambari Project POM</name>
   <packaging>pom</packaging>
   <packaging>pom</packaging>

+ 15 - 0
ambari-server/conf/unix/ambari-env.sh

@@ -1 +1,16 @@
+# 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.
+
 AMBARI_PASSHPHRASE="DEV"
 AMBARI_PASSHPHRASE="DEV"

+ 17 - 0
ambari-server/conf/unix/ambari.properties

@@ -1,3 +1,20 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
 security.server.keys_dir = /var/lib/ambari-server/keys
 security.server.keys_dir = /var/lib/ambari-server/keys
 resources.dir = /var/lib/ambari-server/resources
 resources.dir = /var/lib/ambari-server/resources
 jdk.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jdk-6u31-linux-x64.bin
 jdk.url=http://public-repo-1.hortonworks.com/ARTIFACTS/jdk-6u31-linux-x64.bin

+ 2 - 2
ambari-server/derby.log

@@ -1,6 +1,6 @@
 ----------------------------------------------------------------
 ----------------------------------------------------------------
-Mon Dec 10 15:32:34 PST 2012:
-Booting Derby version The Apache Software Foundation - Apache Derby - 10.9.1.0 - (1344872): instance a816c00e-013b-8729-b0b0-000003feb140 
+Mon Jan 07 23:30:20 PST 2013:
+Booting Derby version The Apache Software Foundation - Apache Derby - 10.9.1.0 - (1344872): instance a816c00e-013c-1911-2686-000003d87098 
 on database directory memory:/Users/mahadev/workspace/ambari-workspace/ambari-git/ambari-server/myDB  with class loader sun.misc.Launcher$AppClassLoader@27a8c4e7 
 on database directory memory:/Users/mahadev/workspace/ambari-workspace/ambari-git/ambari-server/myDB  with class loader sun.misc.Launcher$AppClassLoader@27a8c4e7 
 Loaded from file:/Users/mahadev/.m2/repository/org/apache/derby/derby/10.9.1.0/derby-10.9.1.0.jar
 Loaded from file:/Users/mahadev/.m2/repository/org/apache/derby/derby/10.9.1.0/derby-10.9.1.0.jar
 java.vendor=Apple Inc.
 java.vendor=Apple Inc.

+ 13 - 0
ambari-server/exclude.xml

@@ -1,4 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed 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. See accompanying LICENSE file.
+-->
 
 
 <FindBugsFilter>
 <FindBugsFilter>
 
 

+ 26 - 20
ambari-server/pom.xml

@@ -1,19 +1,22 @@
 <?xml version="1.0"?>
 <?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. -->
+<!--
+  Licensed 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. See accompanying LICENSE file.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <parent>
   <parent>
     <groupId>org.apache.ambari</groupId>
     <groupId>org.apache.ambari</groupId>
     <artifactId>ambari-project</artifactId>
     <artifactId>ambari-project</artifactId>
-    <version>1.0.3-SNAPSHOT</version>
+    <version>1.2.0-SNAPSHOT</version>
     <relativePath>../ambari-project</relativePath>
     <relativePath>../ambari-project</relativePath>
   </parent>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <modelVersion>4.0.0</modelVersion>
@@ -21,7 +24,7 @@
   <artifactId>ambari-server</artifactId>
   <artifactId>ambari-server</artifactId>
   <packaging>jar</packaging>
   <packaging>jar</packaging>
   <name>Ambari Server</name>
   <name>Ambari Server</name>
-  <version>1.0.3-SNAPSHOT</version>
+  <version>1.2.0-SNAPSHOT</version>
   <description>Ambari Server</description>
   <description>Ambari Server</description>
   <properties>
   <properties>
     <python.ver>python &gt;= 2.6</python.ver>
     <python.ver>python &gt;= 2.6</python.ver>
@@ -48,7 +51,18 @@
       <plugin>
       <plugin>
         <groupId>org.apache.rat</groupId>
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
         <artifactId>apache-rat-plugin</artifactId>
+          <version>0.8</version>
         <configuration>
         <configuration>
+          <numUnapprovedLicenses>8</numUnapprovedLicenses>
+          <excludes>
+              <exclude>pass.txt</exclude>
+              <exclude>derby.log</exclude>
+              <exclude>src/test/resources/users.ldif</exclude>
+              <exclude>src/main/resources/ca.config</exclude>
+              <exclude>src/main/resources/db/serial</exclude>
+              <exclude>src/main/resources/db/index.txt</exclude>
+              <exclude>conf/unix/ca.config</exclude>
+          </excludes>
           <includes>
           <includes>
             <include>pom.xml</include>
             <include>pom.xml</include>
           </includes>
           </includes>
@@ -272,10 +286,6 @@
       <groupId>commons-io</groupId>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
       <artifactId>commons-io</artifactId>
     </dependency>
     </dependency>
-    <dependency>
-      <groupId>com.google.inject</groupId>
-      <artifactId>guice</artifactId>
-    </dependency>
     <dependency>
     <dependency>
       <groupId>com.google.inject.extensions</groupId>
       <groupId>com.google.inject.extensions</groupId>
       <artifactId>guice-assistedinject</artifactId>
       <artifactId>guice-assistedinject</artifactId>
@@ -340,10 +350,6 @@
       <groupId>org.eclipse.persistence</groupId>
       <groupId>org.eclipse.persistence</groupId>
       <artifactId>eclipselink</artifactId>
       <artifactId>eclipselink</artifactId>
     </dependency>
     </dependency>
-    <dependency>
-      <groupId>postgresql</groupId>
-      <artifactId>postgresql</artifactId>
-    </dependency>
     <dependency>
     <dependency>
       <groupId>org.mockito</groupId>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <artifactId>mockito-core</artifactId>

+ 20 - 1
ambari-server/sbin/ambari-server

@@ -2,6 +2,22 @@
 # description: ambari-server daemon
 # description: ambari-server daemon
 # processname: ambari-server
 # processname: ambari-server
 
 
+# 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.
+
 # /etc/init.d/ambari-server
 # /etc/init.d/ambari-server
 
 
 export PATH=/usr/lib/ambari-server/*:$PATH
 export PATH=/usr/lib/ambari-server/*:$PATH
@@ -59,7 +75,10 @@ case "$1" in
         ;;
         ;;
   setup)
   setup)
         echo -e "Run postgresql initdb"
         echo -e "Run postgresql initdb"
-        /sbin/service postgresql initdb
+        initdb_res=`/sbin/service postgresql initdb`
+        if [ "0" == "$?" ]; then
+          echo -e "${initdb_res}"
+        fi
         echo -e "Run postgresql start"
         echo -e "Run postgresql start"
         /sbin/service postgresql start
         /sbin/service postgresql start
         echo -e "Setup ambari-server"
         echo -e "Setup ambari-server"

+ 0 - 18
ambari-server/src/examples/spec.json

@@ -1,21 +1,3 @@
-/**
- * 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.
- */
-
 {
 {
   "stack":{
   "stack":{
     "comment":"Stack Definition defines where the artifacts need to be fetched from.""name":"hdp-1.0.1",
     "comment":"Stack Definition defines where the artifacts need to be fetched from.""name":"hdp-1.0.1",

+ 17 - 0
ambari-server/src/main/conf/ambari.properties

@@ -1 +1,18 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# 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.
 metadata.path=src/main/resources/stacks
 metadata.path=src/main/resources/stacks

+ 34 - 0
ambari-server/src/main/java/org/apache/ambari/server/DuplicateResourceException.java

@@ -0,0 +1,34 @@
+/**
+ * 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;
+
+/**
+ * Thrown when an attempt is made to create an already existing resource.
+ */
+public class DuplicateResourceException extends AmbariException {
+
+  /**
+   * Constructor.
+   *
+   * @param message  message
+   */
+  public DuplicateResourceException(String message) {
+    super(message);
+  }
+}

+ 4 - 0
ambari-server/src/main/java/org/apache/ambari/server/HostNotFoundException.java

@@ -24,4 +24,8 @@ public class HostNotFoundException extends ObjectNotFoundException {
   public HostNotFoundException(String hostname) {
   public HostNotFoundException(String hostname) {
     super("Host not found, hostname=" + hostname);
     super("Host not found, hostname=" + hostname);
   }
   }
+
+  public HostNotFoundException(String clusterName, String hostname) {
+    super("Host not found, cluster=" + clusterName + ", hostname=" + hostname);
+  }
 }
 }

+ 44 - 0
ambari-server/src/main/java/org/apache/ambari/server/ParentObjectNotFoundException.java

@@ -0,0 +1,44 @@
+/**
+ * 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;
+
+/**
+ * Indicates that a parent of a resource doesn't exist.
+ */
+public class ParentObjectNotFoundException extends AmbariException {
+
+  /**
+   * Constructor.
+   *
+   * @param msg    message
+   * @param cause  the root cause
+   */
+  public ParentObjectNotFoundException(String msg, ObjectNotFoundException cause) {
+    super(msg + ".  " + cause.getMessage(), cause);
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param message message
+   */
+  public ParentObjectNotFoundException(String message) {
+    super(message);
+  }
+}

+ 1 - 0
ambari-server/src/main/java/org/apache/ambari/server/actionmanager/Stage.java

@@ -199,6 +199,7 @@ public class Stage {
     }
     }
 
 
     if (execCmdList.contains(wrapper)) {
     if (execCmdList.contains(wrapper)) {
+      //todo: proper exception
       throw new RuntimeException(
       throw new RuntimeException(
           "Setting the execution command second time for same stage: stage="
           "Setting the execution command second time for same stage: stage="
               + this.getActionId() + ", host=" + host + ", role=" + role);
               + this.getActionId() + ", host=" + host + ", role=" + role);

+ 48 - 56
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/BaseManagementHandler.java

@@ -19,16 +19,19 @@
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.resources.ResourceInstance;
-import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
-import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
-import org.apache.ambari.server.api.services.PersistenceManager;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.ResultImpl;
 import org.apache.ambari.server.api.services.ResultImpl;
+import org.apache.ambari.server.api.services.persistence.PersistenceManager;
+import org.apache.ambari.server.api.services.persistence.PersistenceManagerImpl;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.api.util.TreeNode;
-import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
 import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
@@ -36,8 +39,22 @@ import java.util.Set;
 /**
 /**
  * Base handler for operations that persist state to the back-end.
  * Base handler for operations that persist state to the back-end.
  */
  */
-public class BaseManagementHandler implements RequestHandler {
-  @Override
+public abstract class BaseManagementHandler implements RequestHandler {
+
+  /**
+   * Logger instance.
+   */
+  protected final static Logger LOG =
+      LoggerFactory.getLogger(BaseManagementHandler.class);
+
+  /**
+   * PersistenceManager implementation.
+   */
+  PersistenceManager m_pm = new PersistenceManagerImpl(getClusterController());
+
+  protected BaseManagementHandler() {
+  }
+
   public Result handleRequest(Request request) {
   public Result handleRequest(Request request) {
     ResourceInstance resource = request.getResource();
     ResourceInstance resource = request.getResource();
     Predicate queryPredicate = request.getQueryPredicate();
     Predicate queryPredicate = request.getQueryPredicate();
@@ -45,71 +62,46 @@ public class BaseManagementHandler implements RequestHandler {
       resource.getQuery().setUserPredicate(queryPredicate);
       resource.getQuery().setUserPredicate(queryPredicate);
     }
     }
 
 
-    return handleRequest(request.getPersistenceManager(), resource,
-        request.getHttpBodyProperties(), request.getURI());
+    return handleRequest(resource, request.getHttpBodyProperties());
   }
   }
 
 
-  protected Result handleRequest(PersistenceManager pm, ResourceInstance resource,
-                                 Set<Map<String, Object>> setProperties, String uri) {
-
-    return createResult(uri, pm.persist(resource, setProperties));
+  protected Result handleRequest(ResourceInstance resource, Set<Map<String, Object>> setProperties) {
+    return persist(resource, setProperties);
   }
   }
 
 
-  private Result createResult(String uri, RequestStatus requestStatus) {
-    boolean isSynchronous = requestStatus.getStatus() == RequestStatus.Status.Complete;
+  protected Result createResult(RequestStatus requestStatus) {
 
 
-    Result result = new ResultImpl(isSynchronous);
-    TreeNode<Resource> tree = result.getResultTree();
-
-    Set<Resource> setResources = requestStatus.getAssociatedResources();
-    TreeNode<Resource> resourcesNode = null;
-    if (! setResources.isEmpty()) {
-      resourcesNode = tree.addChild(null, "resources");
-    }
-    int count = 1;
-    for (Resource resource : setResources) {
-      //todo: provide a more meaningful node name
-      resourcesNode.addChild(resource, resource.getType() + ":" + count++);
-    }
+    boolean            isSynchronous = requestStatus.getStatus() == RequestStatus.Status.Complete;
+    Result             result        = new ResultImpl(isSynchronous);
+    TreeNode<Resource> tree          = result.getResultTree();
 
 
     if (! isSynchronous) {
     if (! isSynchronous) {
-      Resource requestResource = requestStatus.getRequestResource();
-      TreeNode<Resource> r = tree.addChild(requestResource, "request");
-      r.setProperty("href", buildRequestHref(uri, requestStatus));
+      tree.addChild(requestStatus.getRequestResource(), "request");
     }
     }
 
 
-    return result;
-  }
-
-  private String buildRequestHref(String uri, RequestStatus requestStatus) {
-    StringBuilder sb = new StringBuilder();
-    String[] toks = uri.split("/");
+    //todo: currently always empty
+    Set<Resource> setResources = requestStatus.getAssociatedResources();
+    if (! setResources.isEmpty()) {
+      TreeNode<Resource> resourcesNode = tree.addChild(null, "resources");
 
 
-    for (int i = 0; i < toks.length; ++i) {
-      String s = toks[i];
-      sb.append(s).append('/');
-      if ("clusters".equals(s)) {
-        sb.append(toks[i + 1]).append('/');
-        break;
+      int count = 1;
+      for (Resource resource : setResources) {
+        //todo: provide a more meaningful node name
+        resourcesNode.addChild(resource, resource.getType() + ":" + count++);
       }
       }
     }
     }
 
 
-    //todo: shouldn't know property name
-    Object requestId = requestStatus.getRequestResource().getPropertyValue(
-        PropertyHelper.getPropertyId("Requests", "id"));
-
-    sb.append("requests/").append(requestId);
-
-    return sb.toString();
-  }
-
-  //todo: How to get reference to factory?
-  protected ResourceInstanceFactory getResourceFactory() {
-    return new ResourceInstanceFactoryImpl();
+    return result;
   }
   }
 
 
-  //todo: how to get cluster controller?
+  //todo: controller should be injected
   protected ClusterController getClusterController() {
   protected ClusterController getClusterController() {
     return ClusterControllerHelper.getClusterController();
     return ClusterControllerHelper.getClusterController();
   }
   }
+
+  protected PersistenceManager getPersistenceManager() {
+    return m_pm;
+  }
+
+  protected abstract Result persist(ResourceInstance r, Set<Map<String, Object>> properties);
 }
 }

+ 42 - 4
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java

@@ -18,18 +18,56 @@
 
 
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
+import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.services.*;
 import org.apache.ambari.server.api.services.*;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.controller.spi.*;
+
+import java.util.Map;
+import java.util.Set;
 
 
 
 
 /**
 /**
  * Responsible for create requests.
  * Responsible for create requests.
  */
  */
 public class CreateHandler extends BaseManagementHandler {
 public class CreateHandler extends BaseManagementHandler {
+
   @Override
   @Override
-  public Result handleRequest(Request request) {
-    Result result = super.handleRequest(request);
-    //todo: what to return from create?
-    //todo: create specific exceptions
+  protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+    Result result;
+    try {
+      RequestStatus status = getPersistenceManager().create(r, properties);
+
+      result = createResult(status);
+
+      if (result.isSynchronous()) {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.CREATED));
+      } else {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.ACCEPTED));
+      }
+
+    } catch (UnsupportedPropertyException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
+    } catch (NoSuchParentResourceException e) {
+      //todo: is this the correct status code?
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e.getMessage()));
+    } catch (SystemException e) {
+      if (LOG.isErrorEnabled()) {
+        LOG.error("Caught a system exception while attempting to create a resource", e.getMessage());
+      }
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e.getMessage()));
+    } catch (ResourceAlreadyExistsException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.CONFLICT, e.getMessage()));
+    } catch(IllegalArgumentException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
+    } catch (RuntimeException e) {
+      if (LOG.isErrorEnabled()) {
+        LOG.error("Caught a runtime exception while attempting to create a resource", e);
+      }
+      //result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e.getMessage()));
+      throw e;
+    }
+
     return result;
     return result;
   }
   }
 }
 }

+ 38 - 5
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/DeleteHandler.java

@@ -18,16 +18,49 @@
 
 
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
-import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultImpl;
+import org.apache.ambari.server.controller.spi.*;
+
+import java.util.Map;
+import java.util.Set;
 
 
 /**
 /**
  * Responsible for delete requests.
  * Responsible for delete requests.
  */
  */
-public class DeleteHandler extends BaseManagementHandler {
+public class DeleteHandler extends BaseManagementHandler implements RequestHandler {
+
   @Override
   @Override
-  public Result handleRequest(Request request) {
-    //todo: delete specific return information, delete specific exceptions
-    return super.handleRequest(request);
+  protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+    Result result;
+      try {
+        RequestStatus status = getPersistenceManager().delete(r, properties);
+        result = createResult(status);
+
+        if (result.isSynchronous()) {
+          result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK));
+        } else {
+          result.setResultStatus(new ResultStatus(ResultStatus.STATUS.ACCEPTED));
+        }
+      } catch (SystemException e) {
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
+      } catch (NoSuchParentResourceException e) {
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
+      } catch (NoSuchResourceException e) {
+        if (r.isCollectionResource()) {
+          //todo: The query didn't match any resource so no resources were updated.
+          //todo: 200 may be ok but we need to return a collection
+          //todo: of resources that were updated.
+          result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK, e));
+        } else {
+          result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
+        }
+      } catch (UnsupportedPropertyException e) {
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+      }
+
+    return result;
   }
   }
 }
 }

+ 51 - 16
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/QueryCreateHandler.java

@@ -19,14 +19,15 @@
 
 
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.query.Query;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
+import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultImpl;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.api.util.TreeNode;
-import org.apache.ambari.server.controller.spi.ClusterController;
-import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.*;
 
 
 import java.util.*;
 import java.util.*;
 
 
@@ -35,28 +36,27 @@ import java.util.*;
  */
  */
 public class QueryCreateHandler extends BaseManagementHandler {
 public class QueryCreateHandler extends BaseManagementHandler {
 
 
+  private RequestHandler m_readHandler = new ReadHandler();
+
   @Override
   @Override
   public Result handleRequest(Request request) {
   public Result handleRequest(Request request) {
-    ResourceInstance resource = request.getResource();
-    Query query = resource.getQuery();
-    query.setUserPredicate(request.getQueryPredicate());
+    Result queryResult = getReadHandler().handleRequest(request);
+    if (queryResult.getStatus().isErrorState() ||
+        queryResult.getResultTree().getChildren().isEmpty()) {
 
 
-    Result queryResult;
-    try {
-      //todo: only care about primary key
-      queryResult = query.execute();
-    } catch (AmbariException e) {
-      //TODO: exceptions
-      throw new RuntimeException("An exception occurred executing the query portion of the request: " + e, e);
+      //return the query result if result has error state or contains no resources
+      //todo: For case where no resources are returned, will return 200 ok.
+      //todo: What is the appropriate status code?
+      return queryResult;
     }
     }
 
 
+    ResourceInstance resource = request.getResource();
     Resource.Type createType = getCreateType(request.getHttpBody(), resource);
     Resource.Type createType = getCreateType(request.getHttpBody(), resource);
     Set<Map<String, Object>> setProperties = buildCreateSet(request, queryResult, createType);
     Set<Map<String, Object>> setProperties = buildCreateSet(request, queryResult, createType);
     ResourceInstance createResource = getResourceFactory().createResource(
     ResourceInstance createResource = getResourceFactory().createResource(
         createType, request.getResource().getIds());
         createType, request.getResource().getIds());
 
 
-    return super.handleRequest(request.getPersistenceManager(),
-        createResource, setProperties, request.getURI());
+    return super.handleRequest(createResource, setProperties);
   }
   }
 
 
   private Set<Map<String, Object>> buildCreateSet(Request request, Result queryResult, Resource.Type createType) {
   private Set<Map<String, Object>> buildCreateSet(Request request, Result queryResult, Resource.Type createType) {
@@ -91,4 +91,39 @@ public class QueryCreateHandler extends BaseManagementHandler {
     ResourceInstance res =  resource.getSubResources().get(requestBody.substring(startIdx, endIdx));
     ResourceInstance res =  resource.getSubResources().get(requestBody.substring(startIdx, endIdx));
     return res == null ? null : res.getResourceDefinition().getType();
     return res == null ? null : res.getResourceDefinition().getType();
   }
   }
+
+  @Override
+  protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+    Result result;
+    try {
+      RequestStatus status = getPersistenceManager().create(r, properties);
+
+      result = createResult(status);
+
+      if (result.isSynchronous()) {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.CREATED));
+      } else {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.ACCEPTED));
+      }
+
+    } catch (UnsupportedPropertyException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+    } catch (ResourceAlreadyExistsException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.CONFLICT, e));
+    } catch (NoSuchParentResourceException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
+    } catch (SystemException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
+    }
+
+    return result;
+  }
+
+  protected ResourceInstanceFactory getResourceFactory() {
+    return new ResourceInstanceFactoryImpl();
+  }
+
+  protected RequestHandler getReadHandler() {
+    return m_readHandler;
+  }
 }
 }

+ 53 - 12
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java

@@ -19,11 +19,14 @@
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.ResultImpl;
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.query.Query;
 import org.apache.ambari.server.api.query.Query;
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 import java.util.Map;
 import java.util.Map;
 
 
@@ -32,24 +35,62 @@ import java.util.Map;
  */
  */
 public class ReadHandler implements RequestHandler {
 public class ReadHandler implements RequestHandler {
 
 
+  /**
+   * Logger instance.
+   */
+  private final static Logger LOG =
+      LoggerFactory.getLogger(ReadHandler.class);
+
   @Override
   @Override
   public Result handleRequest(Request request) {
   public Result handleRequest(Request request) {
     Query query = request.getResource().getQuery();
     Query query = request.getResource().getQuery();
 
 
+    try {
+      addFieldsToQuery(request, query);
+    } catch (IllegalArgumentException e) {
+      return new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
+    }
+
+    query.setUserPredicate(request.getQueryPredicate());
+    Result result;
+    try {
+      result = query.execute();
+      result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK));
+    } catch (SystemException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
+    } catch (NoSuchParentResourceException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e.getMessage()));
+    } catch (UnsupportedPropertyException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e.getMessage()));
+    } catch (NoSuchResourceException e) {
+      if (request.getQueryPredicate() == null) {
+        // no predicate specified, resource requested by id
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e.getMessage()));
+      } else {
+        // resource(s) requested using predicate
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK, e));
+        result.getResultTree().setProperty("isCollection", "true");
+      }
+    } catch (IllegalArgumentException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
+          "Invalid Request: " + e.getMessage()));
+    } catch (RuntimeException e) {
+      if (LOG.isErrorEnabled()) {
+        LOG.error("Caught a runtime exception executing a query", e);
+      }
+      //result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
+      throw e;
+    }
+    return result;
+  }
+
+  private void addFieldsToQuery(Request request, Query query) throws IllegalArgumentException {
     //Partial response
     //Partial response
     for (Map.Entry<String, TemporalInfo> entry : request.getFields().entrySet()) {
     for (Map.Entry<String, TemporalInfo> entry : request.getFields().entrySet()) {
       // Iterate over map and add props/temporalInfo
       // Iterate over map and add props/temporalInfo
       String propertyId = entry.getKey();
       String propertyId = entry.getKey();
-      query.addProperty(PropertyHelper.getPropertyCategory(propertyId), PropertyHelper.getPropertyName(propertyId), entry.getValue());
-    }
-
-   query.setUserPredicate(request.getQueryPredicate());
-
-    try {
-      return query.execute();
-    } catch (AmbariException e) {
-      //TODO: exceptions
-      throw new RuntimeException("An exception occurred processing the request: " + e, e);
+      query.addProperty(PropertyHelper.getPropertyCategory(propertyId),
+          PropertyHelper.getPropertyName(propertyId), entry.getValue());
     }
     }
   }
   }
 }
 }

+ 1 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/RequestHandler.java

@@ -18,6 +18,7 @@
 
 
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
 
 

+ 35 - 4
ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java

@@ -18,18 +18,49 @@
 
 
 package org.apache.ambari.server.api.handlers;
 package org.apache.ambari.server.api.handlers;
 
 
+import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.services.*;
 import org.apache.ambari.server.api.services.*;
+import org.apache.ambari.server.controller.spi.*;
+
+import java.util.Map;
+import java.util.Set;
 
 
 
 
 /**
 /**
  * Responsible for update requests.
  * Responsible for update requests.
  */
  */
 public class UpdateHandler extends BaseManagementHandler {
 public class UpdateHandler extends BaseManagementHandler {
+
   @Override
   @Override
-  public Result handleRequest(Request request) {
-    Result result = super.handleRequest(request);
-    //todo: what to return from update?
-    //todo: update specific exceptions
+  protected Result persist(ResourceInstance r, Set<Map<String, Object>> properties) {
+    Result result;
+    try {
+      RequestStatus status = getPersistenceManager().update(r, properties);
+
+      result = createResult(status);
+      if (result.isSynchronous()) {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.OK));
+      } else {
+        result.setResultStatus(new ResultStatus(ResultStatus.STATUS.ACCEPTED));
+      }
+
+    } catch (UnsupportedPropertyException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+    } catch (NoSuchParentResourceException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
+    } catch (NoSuchResourceException e) {
+      if (r.isCollectionResource()) {
+        //todo: what is the correct status code here.  The query didn't match any resource
+        //todo: so no resource were updated.  200 may be ok but we would need to return a collection
+        //todo: of resources that were updated.
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK, e));
+      } else {
+        result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.NOT_FOUND, e));
+      }
+    } catch (SystemException e) {
+      result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
+    }
+
     return result;
     return result;
   }
   }
 }
 }

+ 11 - 7
ambari-server/src/main/java/org/apache/ambari/server/api/query/Query.java

@@ -19,9 +19,7 @@
 package org.apache.ambari.server.api.query;
 package org.apache.ambari.server.api.query;
 
 
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.apache.ambari.server.controller.spi.*;
 
 
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
@@ -36,9 +34,9 @@ public interface Query {
    * Add a property to the query.
    * Add a property to the query.
    * This is the select portion of the query.
    * This is the select portion of the query.
    *
    *
-   * @param group    the group name that contains the property
-   * @param property the property name
-   * @param temporalInfo
+   * @param group         the group name that contains the property
+   * @param property      the property name
+   * @param temporalInfo  temporal information for the property
    */
    */
   public void addProperty(String group, String property, TemporalInfo temporalInfo);
   public void addProperty(String group, String property, TemporalInfo temporalInfo);
 
 
@@ -64,8 +62,14 @@ public interface Query {
    * Execute the query.
    * Execute the query.
    *
    *
    * @return the result of the query.
    * @return the result of the query.
+   *
+   * @throws UnsupportedPropertyException if the query or query predicate contains invalid non-existent properties
+   * @throws SystemException an internal error occurred
+   * @throws NoSuchResourceException the query didn't match any resources
+   * @throws NoSuchParentResourceException a specified parent resource doesn't exist
    */
    */
-  public Result execute() throws AmbariException;
+  public Result execute()
+      throws UnsupportedPropertyException, SystemException, NoSuchResourceException, NoSuchParentResourceException;
 
 
   /**
   /**
    * Return the predicate used to identify the associated resource.  This includes the primary key and
    * Return the predicate used to identify the associated resource.  This includes the primary key and

+ 16 - 15
ambari-server/src/main/java/org/apache/ambari/server/api/query/QueryImpl.java

@@ -23,7 +23,6 @@ import org.apache.ambari.server.api.services.ResultImpl;
 import org.apache.ambari.server.api.util.TreeNodeImpl;
 import org.apache.ambari.server.api.util.TreeNodeImpl;
 import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
 import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.predicate.AndPredicate;
 import org.apache.ambari.server.controller.predicate.AndPredicate;
 import org.apache.ambari.server.controller.predicate.BasePredicate;
 import org.apache.ambari.server.controller.predicate.BasePredicate;
 import org.apache.ambari.server.controller.predicate.EqualsPredicate;
 import org.apache.ambari.server.controller.predicate.EqualsPredicate;
@@ -119,9 +118,10 @@ public class QueryImpl implements Query {
       // not a local category/property
       // not a local category/property
       boolean success = addPropertyToSubResource(category, property, temporalInfo);
       boolean success = addPropertyToSubResource(category, property, temporalInfo);
       if (!success) {
       if (!success) {
-        //TODO
-        throw new RuntimeException("Attempted to add invalid property to resource.  Resource=" +
-            m_resource.getResourceDefinition().getType() + ", Property: Category=" + category + " Field=" + property);
+        //TODO.  Remove when handled by back end
+        String propString = category == null ? property : property == null ? category : category + '/' + property;
+        throw new IllegalArgumentException("An invalid resource property was requested.  Resource: " +
+            m_resource.getResourceDefinition().getType() + ", Property: " + propString);
       }
       }
     }
     }
   }
   }
@@ -132,9 +132,10 @@ public class QueryImpl implements Query {
   }
   }
 
 
   @Override
   @Override
-  public Result execute() throws AmbariException {
-    Result result = createResult();
+  public Result execute()
+      throws UnsupportedPropertyException, SystemException, NoSuchResourceException, NoSuchParentResourceException {
 
 
+    Result result = createResult();
     Resource.Type resourceType = m_resource.getResourceDefinition().getType();
     Resource.Type resourceType = m_resource.getResourceDefinition().getType();
     if (m_resource.getIds().get(resourceType) == null) {
     if (m_resource.getIds().get(resourceType) == null) {
       addCollectionProperties(resourceType);
       addCollectionProperties(resourceType);
@@ -147,14 +148,8 @@ public class QueryImpl implements Query {
     }
     }
 
 
     Predicate predicate = createPredicate(m_resource);
     Predicate predicate = createPredicate(m_resource);
-    Iterable<Resource> iterResource = null;
-
-    try {
-      iterResource = getClusterController().getResources(
-          resourceType, createRequest(), predicate);
-    } catch (UnsupportedPropertyException e) {
-      // TODO ...
-    }
+    Iterable<Resource> iterResource = getClusterController().getResources(
+        resourceType, createRequest(), predicate);
 
 
     TreeNode<Resource> tree = result.getResultTree();
     TreeNode<Resource> tree = result.getResultTree();
     int count = 1;
     int count = 1;
@@ -235,7 +230,13 @@ public class QueryImpl implements Query {
   }
   }
 
 
   private boolean addCategory(String category, String name, TemporalInfo temporalInfo) {
   private boolean addCategory(String category, String name, TemporalInfo temporalInfo) {
-    name = category != null ? category + '/' + name : name;
+    if (category != null) {
+      if (name != null && ! name.isEmpty()) {
+        name = category + '/' + name;
+      } else  {
+        name = category;
+      }
+    }
     TreeNode<Set<String>> node = m_treeAllProperties.getChild(name);
     TreeNode<Set<String>> node = m_treeAllProperties.getChild(name);
     if (node == null) {
     if (node == null) {
       return false;
       return false;

+ 32 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/resources/RequestResourceDefinition.java

@@ -19,9 +19,12 @@
 package org.apache.ambari.server.api.resources;
 package org.apache.ambari.server.api.resources;
 
 
 
 
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource;
 
 
 import java.util.Collections;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
 
 
@@ -51,4 +54,33 @@ public class RequestResourceDefinition extends BaseResourceDefinition {
   public Set<SubResourceDefinition> getSubResourceDefinitions() {
   public Set<SubResourceDefinition> getSubResourceDefinitions() {
       return Collections.singleton(new SubResourceDefinition(Resource.Type.Task));
       return Collections.singleton(new SubResourceDefinition(Resource.Type.Task));
   }
   }
+
+  @Override
+  public List<PostProcessor> getPostProcessors() {
+    return Collections.<PostProcessor>singletonList(new RequestHrefPostProcessor());
+  }
+
+  private class RequestHrefPostProcessor implements PostProcessor {
+    @Override
+    public void process(Request request, TreeNode<Resource> resultNode, String href) {
+      StringBuilder sb = new StringBuilder();
+      String[] toks = href.split("/");
+
+      for (int i = 0; i < toks.length; ++i) {
+        String s = toks[i];
+        sb.append(s).append('/');
+        if ("clusters".equals(s)) {
+          sb.append(toks[i + 1]).append('/');
+          break;
+        }
+      }
+
+      Object requestId = resultNode.getObject().getPropertyValue(getClusterController().
+          getSchema(Resource.Type.Request).getKeyPropertyId(Resource.Type.Request));
+
+      sb.append("requests/").append(requestId);
+
+      resultNode.setProperty("href", sb.toString());
+    }
+  }
 }
 }

+ 7 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstance.java

@@ -67,4 +67,11 @@ public interface ResourceInstance {
    * @return all sub-resource instances
    * @return all sub-resource instances
    */
    */
   public Map<String, ResourceInstance> getSubResources();
   public Map<String, ResourceInstance> getSubResources();
+
+  /**
+   * Determine if resource is a collection resource.
+   *
+   * @return true if the resource is a collection resource; false otherwise
+   */
+  public boolean isCollectionResource();
 }
 }

+ 5 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceImpl.java

@@ -126,6 +126,11 @@ public class ResourceInstanceImpl implements ResourceInstance {
     return m_mapSubResources;
     return m_mapSubResources;
   }
   }
 
 
+  @Override
+  public boolean isCollectionResource() {
+    return getIds().get(getResourceDefinition().getType()) == null;
+  }
+
   @Override
   @Override
   public boolean equals(Object o) {
   public boolean equals(Object o) {
     if (this == o) return true;
     if (this == o) return true;

+ 241 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseRequest.java

@@ -0,0 +1,241 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.*;
+import org.apache.ambari.server.api.services.parsers.JsonPropertyParser;
+import org.apache.ambari.server.api.services.parsers.RequestBodyParser;
+import org.apache.ambari.server.api.services.serializers.JsonSerializer;
+import org.apache.ambari.server.api.services.serializers.ResultSerializer;
+import org.apache.ambari.server.controller.internal.TemporalInfoImpl;
+import org.apache.ambari.server.controller.predicate.*;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Request implementation.
+ */
+public abstract class BaseRequest implements Request {
+
+  /**
+   * URI information
+   */
+  private UriInfo m_uriInfo;
+
+  /**
+   * Http headers
+   */
+  private HttpHeaders m_headers;
+
+  /**
+   * Http Body
+   */
+  private String m_body;
+
+
+  /**
+   * Predicate operators.
+   */
+  private Pattern m_pattern = Pattern.compile("!=|>=|<=|=|>|<");
+
+  /**
+   * Associated resource definition
+   */
+  private ResourceInstance m_resource;
+
+
+  /**
+   * Constructor.
+   *
+   * @param headers      http headers
+   * @param body         http body
+   * @param uriInfo      uri information
+   * @param resource     associated resource definition
+   */
+  public BaseRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+
+    m_headers  = headers;
+    m_body     = body;
+    m_uriInfo  = uriInfo;
+    m_resource = resource;
+  }
+
+  @Override
+  public ResourceInstance getResource() {
+    return m_resource;
+  }
+
+  @Override
+  public String getURI() {
+    try {
+      return URLDecoder.decode(m_uriInfo.getRequestUri().toASCIIString(), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("Unable to decode URI: " + e, e);
+    }
+  }
+
+  @Override
+  public int getAPIVersion() {
+    return 0;
+  }
+
+  @Override
+  public Predicate getQueryPredicate() {
+    //todo: parse during init
+    //not using getQueryParameters because it assumes '=' operator
+    String uri = getURI();
+    int qsBegin = uri.indexOf("?");
+
+    if (qsBegin == -1) return null;
+
+    String[] tokens = uri.substring(qsBegin + 1).split("&");
+
+    Set<BasePredicate> setPredicates = new HashSet<BasePredicate>();
+    for (String outerToken : tokens) {
+      if (outerToken != null &&  !outerToken.startsWith("fields")) {
+        setPredicates.add(outerToken.contains("|") ?
+            handleOrPredicate(outerToken) : createPredicate(outerToken));
+      }
+    }
+
+    if (setPredicates.size() == 1) {
+      return setPredicates.iterator().next();
+    } else if (setPredicates.size() > 1) {
+      return new AndPredicate(setPredicates.toArray(new BasePredicate[setPredicates.size()]));
+    } else {
+      return null;
+    }
+  }
+
+  @Override
+  public Map<String, TemporalInfo> getFields() {
+    Map<String, TemporalInfo> mapProperties;
+    String partialResponseFields = m_uriInfo.getQueryParameters().getFirst("fields");
+    if (partialResponseFields == null) {
+      mapProperties = Collections.emptyMap();
+    } else {
+      Set<String> setMatches = new HashSet<String>();
+      // Pattern basically splits a string using ',' as the deliminator unless ',' is between '[' and ']'.
+      // Actually, captures char sequences between ',' and all chars between '[' and ']' including ','.
+      Pattern re = Pattern.compile("[^,\\[]*?\\[[^\\]]*?\\]|[^,]+");
+      Matcher m = re.matcher(partialResponseFields);
+      while (m.find()){
+        for (int groupIdx = 0; groupIdx < m.groupCount() + 1; groupIdx++) {
+          setMatches.add(m.group(groupIdx));
+        }
+      }
+
+      mapProperties = new HashMap<String, TemporalInfo>(setMatches.size());
+      for (String field : setMatches) {
+        TemporalInfo temporalInfo = null;
+        if (field.contains("[")) {
+          String[] temporalData = field.substring(field.indexOf('[') + 1,
+              field.indexOf(']')).split(",");
+          field = field.substring(0, field.indexOf('['));
+          long start = Long.parseLong(temporalData[0].trim());
+          long end   = -1;
+          long step  = -1;
+          if (temporalData.length >= 2) {
+            end = Long.parseLong(temporalData[1].trim());
+            if (temporalData.length == 3) {
+              step = Long.parseLong(temporalData[2].trim());
+            }
+          }
+          temporalInfo = new TemporalInfoImpl(start, end, step);
+        }
+        mapProperties.put(field, temporalInfo);
+      }
+    }
+
+    return mapProperties;
+  }
+
+  @Override
+  public Map<String, List<String>> getHttpHeaders() {
+    return m_headers.getRequestHeaders();
+  }
+
+  @Override
+  public String getHttpBody() {
+    return m_body;
+  }
+
+  @Override
+  public Set<Map<String, Object>> getHttpBodyProperties() {
+    return getHttpBodyParser().parse(getHttpBody());
+  }
+
+  @Override
+  public ResultSerializer getResultSerializer() {
+    return new JsonSerializer();
+  }
+
+  @Override
+  public ResultPostProcessor getResultPostProcessor() {
+    return new ResultPostProcessorImpl(this);
+  }
+
+  private BasePredicate createPredicate(String token) {
+
+    Matcher m = m_pattern.matcher(token);
+    m.find();
+
+    String propertyId = token.substring(0, m.start());
+    String     value      = token.substring(m.end());
+    String     operator   = m.group();
+
+    if (operator.equals("=")) {
+      return new EqualsPredicate<String>(propertyId, value);
+    } else if (operator.equals("!=")) {
+      return new NotPredicate(new EqualsPredicate<String>(propertyId, value));
+    } else if (operator.equals("<")) {
+      return new LessPredicate<String>(propertyId, value);
+    } else if (operator.equals(">"))  {
+      return new GreaterPredicate<String>(propertyId, value);
+    } else if (operator.equals("<=")) {
+      return new LessEqualsPredicate<String>(propertyId, value);
+    } else if (operator.equals(">=")) {
+      return new GreaterEqualsPredicate<String>(propertyId, value);
+    } else {
+      throw new RuntimeException("Unknown operator provided in predicate: " + operator);
+    }
+  }
+
+  private BasePredicate handleOrPredicate(String predicate) {
+    Set<BasePredicate> setPredicates = new HashSet<BasePredicate>();
+    String[] tokens = predicate.split("\\|");
+    for (String tok : tokens) {
+      setPredicates.add(createPredicate(tok));
+    }
+
+    return new OrPredicate(setPredicates.toArray(new BasePredicate[setPredicates.size()]));
+  }
+
+  protected RequestBodyParser getHttpBodyParser() {
+    return new JsonPropertyParser();
+  }
+}

+ 29 - 19
ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java

@@ -18,9 +18,8 @@
 
 
 package org.apache.ambari.server.api.services;
 package org.apache.ambari.server.api.services;
 
 
-import org.apache.ambari.server.api.handlers.DelegatingRequestHandler;
 import org.apache.ambari.server.api.handlers.RequestHandler;
 import org.apache.ambari.server.api.handlers.RequestHandler;
-import org.apache.ambari.server.api.resources.ResourceDefinition;
+import org.apache.ambari.server.api.handlers.RequestHandlerFactory;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactory;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
 import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
@@ -37,8 +36,16 @@ import java.util.Map;
  */
  */
 public abstract class BaseService {
 public abstract class BaseService {
 
 
+  /**
+   * Factory for creating resource instances.
+   */
   private ResourceInstanceFactory m_resourceFactory = new ResourceInstanceFactoryImpl();
   private ResourceInstanceFactory m_resourceFactory = new ResourceInstanceFactoryImpl();
 
 
+  /**
+   * Factory for creating request handlers.
+   */
+  private RequestHandlerFactory m_handlerFactory = new RequestHandlerFactory();
+
   /**
   /**
    * All requests are funneled through this method so that common logic can be executed.
    * All requests are funneled through this method so that common logic can be executed.
    * This consists of creating a {@link Request} instance, invoking the correct {@link RequestHandler} and
    * This consists of creating a {@link Request} instance, invoking the correct {@link RequestHandler} and
@@ -55,12 +62,16 @@ public abstract class BaseService {
   protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
   protected Response handleRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
                                    ResourceInstance resource) {
                                    ResourceInstance resource) {
 
 
-    Request request = getRequestFactory().createRequest(headers, body, uriInfo, requestType, resource);
-    Result result = getRequestHandler().handleRequest(request);
+    Request request = getRequestFactory().createRequest(
+        headers, body, uriInfo, requestType, resource);
+
+    Result result = getRequestHandler(request.getRequestType()).handleRequest(request);
+    if (! result.getStatus().isErrorState()) {
+      request.getResultPostProcessor().process(result);
+    }
 
 
-    return getResponseFactory().createResponse(requestType,
-        request.getResultSerializer().serialize(result, uriInfo),
-        result.isSynchronous());
+    return Response.status(result.getStatus().getStatusCode()).entity(
+        request.getResultSerializer().serialize(result)).build();
   }
   }
 
 
   /**
   /**
@@ -73,25 +84,24 @@ public abstract class BaseService {
   }
   }
 
 
   /**
   /**
-   * Obtain the factory from which to create Response instances.
+   * Obtain the appropriate RequestHandler for the request.
    *
    *
-   * @return the Response factory
+   * @param requestType  the request type
+   *
+   * @return the request handler to invoke
    */
    */
-  ResponseFactory getResponseFactory() {
-    return new ResponseFactory();
+  RequestHandler getRequestHandler(Request.Type requestType) {
+    return m_handlerFactory.getRequestHandler(requestType);
   }
   }
 
 
   /**
   /**
-   * Obtain the appropriate RequestHandler for the request.  At this time all requests are funneled through
-   * a delegating request handler which will ultimately delegate the request to the appropriate concrete
-   * request handler.
+   * Create a resource instance.
    *
    *
-   * @return the request handler to invoke
+   * @param type    the resource type
+   * @param mapIds  all primary and foreign key properties and values
+   *
+   * @return a newly created resource instance
    */
    */
-  RequestHandler getRequestHandler() {
-    return new DelegatingRequestHandler();
-  }
-
   ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
   ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
     return m_resourceFactory.createResource(type, mapIds);
     return m_resourceFactory.createResource(type, mapIds);
   }
   }

+ 47 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/DeleteRequest.java

@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * A DELETE request.
+ */
+public class DeleteRequest extends BaseRequest {
+  /**
+   * Constructor.
+   *
+   * @param headers     http headers
+   * @param body        http body
+   * @param uriInfo     uri information
+   * @param resource    associated resource definition
+   */
+  public DeleteRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+    super(headers, body, uriInfo, resource);
+  }
+
+  @Override
+  public Type getRequestType() {
+    return Type.DELETE;
+  }
+
+}

+ 46 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/GetRequest.java

@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * A GET request.
+ */
+public class GetRequest extends BaseRequest {
+  /**
+   * Constructor.
+   *
+   * @param headers     http headers
+   * @param body        http body
+   * @param uriInfo     uri information
+   * @param resource    associated resource definition
+   */
+  public GetRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+    super(headers, body, uriInfo, resource);
+  }
+
+  @Override
+  public Type getRequestType() {
+    return Type.GET;
+  }
+}

+ 47 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/PostRequest.java

@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * A POST request.
+ */
+public class PostRequest extends BaseRequest {
+  /**
+   * Constructor.
+   *
+   * @param headers     http headers
+   * @param body        http body
+   * @param uriInfo     uri information
+   * @param resource    associated resource definition
+   */
+  public PostRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+    super(headers, body, uriInfo, resource);
+  }
+
+  @Override
+  public Type getRequestType() {
+    return Type.POST;
+  }
+
+}

+ 47 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/PutRequest.java

@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * A PUT request.
+ */
+public class PutRequest extends BaseRequest {
+  /**
+   * Constructor.
+   *
+   * @param headers     http headers
+   * @param body        http body
+   * @param uriInfo     uri information
+   * @param resource    associated resource definition
+   */
+  public PutRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+    super(headers, body, uriInfo, resource);
+  }
+
+  @Override
+  public Type getRequestType() {
+    return Type.PUT;
+  }
+
+}

+ 59 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/QueryPostRequest.java

@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Request for creating sub-resources of instances based on a query.
+ */
+public class QueryPostRequest extends PostRequest {
+  /**
+   * Constructor.
+   *
+   * @param headers      http headers
+   * @param body         http body
+   * @param uriInfo      uri information
+   * @param resource     associated resource instance
+   */
+  public QueryPostRequest(HttpHeaders headers, String body, UriInfo uriInfo, ResourceInstance resource) {
+    super(headers, body, uriInfo, resource);
+  }
+
+  @Override
+  public Set<Map<String, Object>> getHttpBodyProperties() {
+    String httpBody = getHttpBody();
+    //strip array name
+    int startIdx = httpBody.indexOf("[");
+    int endIdx = httpBody.lastIndexOf("]");
+
+    return getHttpBodyParser().parse(httpBody.substring(startIdx, endIdx + 1));
+  }
+
+  @Override
+  public Type getRequestType() {
+    return Type.QUERY_POST;
+  }
+}

+ 0 - 7
ambari-server/src/main/java/org/apache/ambari/server/api/services/Request.java

@@ -125,11 +125,4 @@ public interface Request {
    * @return a set of maps containing the properties contained in the http body
    * @return a set of maps containing the properties contained in the http body
    */
    */
   public Set<Map<String, Object>> getHttpBodyProperties();
   public Set<Map<String, Object>> getHttpBodyProperties();
-
-  /**
-   * Obtain the appropriate persistence manager.
-   *
-   * @return the appropriate persistence manager
-   */
-  public PersistenceManager getPersistenceManager();
 }
 }

+ 14 - 9
ambari-server/src/main/java/org/apache/ambari/server/api/services/RequestFactory.java

@@ -39,15 +39,20 @@ public class RequestFactory {
    */
    */
   public Request createRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
   public Request createRequest(HttpHeaders headers, String body, UriInfo uriInfo, Request.Type requestType,
                                ResourceInstance resource) {
                                ResourceInstance resource) {
-
-    if (requestType == Request.Type.POST &&
-        ! uriInfo.getQueryParameters().isEmpty() &&
-        body != null) {
-
-      return new QueryCreateRequest(headers, body, uriInfo, requestType, resource);
-
-    } else {
-      return new RequestImpl(headers, body, uriInfo, requestType, resource);
+    switch (requestType) {
+      case GET:
+        return new GetRequest(headers, body, uriInfo, resource);
+      case PUT:
+        return new PutRequest(headers, body, uriInfo, resource);
+      case DELETE:
+        return new DeleteRequest(headers, body, uriInfo, resource);
+      case POST:
+        return (uriInfo.getQueryParameters().isEmpty() || body == null) ?
+            new PostRequest(headers, body, uriInfo, resource) :
+            new QueryPostRequest(headers, body, uriInfo, resource);
+      default:
+        throw new IllegalArgumentException("Invalid request type: " + requestType);
     }
     }
   }
   }
+
 }
 }

+ 40 - 2
ambari-server/src/main/java/org/apache/ambari/server/api/services/Result.java

@@ -26,18 +26,56 @@ import org.apache.ambari.server.api.util.TreeNode;
  * Represents a result from a request handler invocation.
  * Represents a result from a request handler invocation.
  */
  */
 public interface Result {
 public interface Result {
+
+  public static enum STATUS { OK(200, "OK", false), CREATED(201, "Created", false), ACCEPTED(202, "Accepted", false),
+    CONFLICT(409, "Resource Conflict", true), NOT_FOUND(404, "Not Found", true), BAD_REQUEST(400, "Bad Request", true),
+    UNAUTHORIZED(401, "Unauthorized", true), FORBIDDEN(403, "Forbidden", true),
+    SERVER_ERROR(500, "Internal Server Error", true);
+
+    private int    m_code;
+    private String m_desc;
+    private boolean m_isErrorState;
+
+    private STATUS(int code, String description, boolean isErrorState) {
+      m_code = code;
+      m_desc = description;
+      m_isErrorState = isErrorState;
+    }
+
+    public int getStatus() {
+      return m_code;
+    }
+
+    public String getDescription() {
+      return m_desc;
+    }
+
+    public boolean isErrorState() {
+      return m_isErrorState;
+    }
+
+    @Override
+    public String toString() {
+      return getDescription();
+    }
+  };
+
   /**
   /**
-   * the results of the request invocation as a Tree structure.
+   * Obtain the results of the request invocation as a Tree structure.
    *
    *
    * @return the results of the request a a Tree structure
    * @return the results of the request a a Tree structure
    */
    */
   public TreeNode<Resource> getResultTree();
   public TreeNode<Resource> getResultTree();
 
 
   /**
   /**
-   * Determine whether the request was handle synchronously.
+   * Determine whether the request was handled synchronously.
    * If the request is synchronous, all work was completed prior to returning.
    * If the request is synchronous, all work was completed prior to returning.
    *
    *
    * @return true if the request was synchronous, false if it was asynchronous
    * @return true if the request was synchronous, false if it was asynchronous
    */
    */
   public boolean isSynchronous();
   public boolean isSynchronous();
+
+  public ResultStatus getStatus();
+
+  public void setResultStatus(ResultStatus status);
 }
 }

+ 30 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultImpl.java

@@ -34,15 +34,35 @@ public class ResultImpl implements Result {
    */
    */
   private boolean m_synchronous;
   private boolean m_synchronous;
 
 
+  /**
+   * Result status.
+   */
+  private ResultStatus m_status;
+
   /**
   /**
    * Tree structure which holds the results
    * Tree structure which holds the results
    */
    */
   private TreeNode<Resource> m_tree = new TreeNodeImpl<Resource>(null, null, null);
   private TreeNode<Resource> m_tree = new TreeNodeImpl<Resource>(null, null, null);
 
 
+
+  /**
+   * Constructor.
+   *
+   * @param synchronous true if request was handled synchronously, false otherwise
+   */
   public ResultImpl(boolean synchronous) {
   public ResultImpl(boolean synchronous) {
     m_synchronous = synchronous;
     m_synchronous = synchronous;
   }
   }
 
 
+  /**
+   * Constructor.
+   *
+   * @param status  result status
+   */
+  public ResultImpl(ResultStatus status) {
+    m_status = status;
+  }
+
   @Override
   @Override
   public TreeNode<Resource> getResultTree() {
   public TreeNode<Resource> getResultTree() {
     return m_tree;
     return m_tree;
@@ -52,5 +72,15 @@ public class ResultImpl implements Result {
   public boolean isSynchronous() {
   public boolean isSynchronous() {
     return m_synchronous;
     return m_synchronous;
   }
   }
+
+  @Override
+  public ResultStatus getStatus() {
+    return m_status;
+  }
+
+  @Override
+  public void setResultStatus(ResultStatus status) {
+    m_status = status;
+  }
 }
 }
 
 

+ 5 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultPostProcessorImpl.java

@@ -18,6 +18,7 @@
 
 
 package org.apache.ambari.server.api.services;
 package org.apache.ambari.server.api.services;
 
 
+import org.apache.ambari.server.api.resources.RequestResourceDefinition;
 import org.apache.ambari.server.api.resources.ResourceDefinition;
 import org.apache.ambari.server.api.resources.ResourceDefinition;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource;
@@ -99,6 +100,7 @@ public class ResultPostProcessorImpl implements ResultPostProcessor {
    * @param resource the root resource
    * @param resource the root resource
    */
    */
   private void registerResourceProcessors(ResourceInstance resource) {
   private void registerResourceProcessors(ResourceInstance resource) {
+    //todo: reconsider registration mechanism
     Resource.Type type = resource.getResourceDefinition().getType();
     Resource.Type type = resource.getResourceDefinition().getType();
     List<ResourceDefinition.PostProcessor> listProcessors = m_mapPostProcessors.get(type);
     List<ResourceDefinition.PostProcessor> listProcessors = m_mapPostProcessors.get(type);
     if (listProcessors == null) {
     if (listProcessors == null) {
@@ -113,6 +115,9 @@ public class ResultPostProcessorImpl implements ResultPostProcessor {
         registerResourceProcessors(child);
         registerResourceProcessors(child);
       }
       }
     }
     }
+
+    // always add Request post processors since they may be returned but will not be a child
+    m_mapPostProcessors.put(Resource.Type.Request, new RequestResourceDefinition().getPostProcessors());
   }
   }
 
 
 }
 }

+ 176 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/ResultStatus.java

@@ -0,0 +1,176 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services;
+
+/**
+ * Result status information.
+ */
+public class ResultStatus {
+
+  /**
+   * STATUS enum. Maps a status to a status code.
+   */
+  public static enum STATUS { OK(200, "OK", false), CREATED(201, "Created", false), ACCEPTED(202, "Accepted", false),
+    CONFLICT(409, "Resource Conflict", true), NOT_FOUND(404, "Not Found", true), BAD_REQUEST(400, "Bad Request", true),
+    UNAUTHORIZED(401, "Unauthorized", true), FORBIDDEN(403, "Forbidden", true),
+    SERVER_ERROR(500, "Internal Server Error", true);
+
+    /**
+     * Status code
+     */
+    private int m_code;
+
+    /**
+     * Description
+     */
+    private String m_desc;
+
+    /**
+     * whether this is an error state
+     */
+    private boolean m_isErrorState;
+
+    /**
+     * Constructor.
+     *
+     * @param code         status code
+     * @param description  description
+     * @param isErrorState whether this is an error state
+     */
+    private STATUS(int code, String description, boolean isErrorState) {
+      m_code = code;
+      m_desc = description;
+      m_isErrorState = isErrorState;
+    }
+
+    /**
+     * Obtain the status code.
+     * This is an http response code.
+     *
+     * @return  the status code
+     */
+    public int getStatus() {
+      return m_code;
+    }
+
+    /**
+     * Obtain a brief description.
+     *
+     * @return the description
+     */
+    public String getDescription() {
+      return m_desc;
+    }
+
+    /**
+     * Whether this status is an error state
+     *
+     * @return true if this is an error state; false otherwise
+     */
+    public boolean isErrorState() {
+      return m_isErrorState;
+    }
+
+    @Override
+    public String toString() {
+      return getDescription();
+    }
+  }
+
+  /**
+   * Status instance
+   */
+  private STATUS m_status;
+
+  /**
+   * Result status message
+   */
+  private String m_msg;
+
+  /**
+   * Constructor.
+   *
+   * @param status result status
+   * @param msg    result msg.  Usually used in case of an error.
+   */
+  public ResultStatus(STATUS status, String msg) {
+    m_status       = status;
+    m_msg          = msg;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param status  result status
+   */
+  public ResultStatus(STATUS status) {
+    m_status = status;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param status  result status
+   * @param e       result exception
+   */
+  public ResultStatus(STATUS status, Exception e) {
+    m_status = status;
+    m_msg = e.toString();
+  }
+
+  /**
+   * Obtain the result status.
+   * The result status contains a status code and a description of the status.
+   *
+   * @return  the result status
+   */
+  public STATUS getStatus() {
+    return m_status;
+  }
+
+  /**
+   * Obtain the status code.
+   * This is a shortcut to obtaining the status code from the associated result status.
+   *
+   * @return the status code
+   */
+  public int getStatusCode() {
+    return m_status.getStatus();
+  }
+
+  /**
+   * Determine whether the status is an error state.
+   * This is a shortcut to getting this information from the associated result status.
+   *
+   * @return true if the status is a result state; false otherwise
+   */
+  public boolean isErrorState() {
+    return m_status.isErrorState();
+  }
+
+  /**
+   * Obtain the result message.
+   * This message is usually used when an exception occurred.
+   *
+   * @return the result message
+   */
+  public String getMessage() {
+    return m_msg;
+  }
+}

+ 45 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/persistence/PersistenceManager.java

@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.persistence;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.*;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Persistence manager which is responsible for persisting a resource state to the back end.
+ * This includes create, update and delete operations.
+ */
+public interface PersistenceManager {
+
+  public RequestStatus create(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException,
+             SystemException;
+
+  public RequestStatus update(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException, SystemException, NoSuchParentResourceException, NoSuchResourceException;
+
+
+  public RequestStatus delete(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException, SystemException, NoSuchParentResourceException, NoSuchResourceException;
+}

+ 94 - 0
ambari-server/src/main/java/org/apache/ambari/server/api/services/persistence/PersistenceManagerImpl.java

@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.persistence;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Persistence Manager implementation.
+ */
+public class PersistenceManagerImpl implements PersistenceManager {
+
+  /**
+   * Cluster Controller reference.
+   */
+  private ClusterController m_controller;
+
+  /**
+   * Constructor.
+   *
+   * @param controller  the cluster controller
+   */
+  public PersistenceManagerImpl(ClusterController controller) {
+    m_controller = controller;
+  }
+
+  @Override
+  public RequestStatus create(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException,
+             SystemException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
+    Map<Resource.Type, String> mapResourceIds = resource.getIds();
+    Resource.Type type = resource.getResourceDefinition().getType();
+    Schema schema = m_controller.getSchema(type);
+
+    if (setProperties.size() == 0) {
+      setProperties.add(new HashMap<String, Object>());
+    }
+
+    for (Map<String, Object> mapProperties : setProperties) {
+      for (Map.Entry<Resource.Type, String> entry : mapResourceIds.entrySet()) {
+        String property = schema.getKeyPropertyId(entry.getKey());
+        if (! mapProperties.containsKey(property)) {
+          mapProperties.put(property, entry.getValue());
+        }
+      }
+    }
+    return m_controller.createResources(type, createControllerRequest(setProperties));
+  }
+
+  @Override
+  public RequestStatus update(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException, SystemException, NoSuchParentResourceException, NoSuchResourceException {
+
+    return m_controller.updateResources(resource.getResourceDefinition().getType(),
+        createControllerRequest(setProperties), resource.getQuery().getPredicate());
+  }
+
+  @Override
+  public RequestStatus delete(ResourceInstance resource, Set<Map<String, Object>> setProperties)
+      throws UnsupportedPropertyException, SystemException, NoSuchParentResourceException, NoSuchResourceException {
+    //todo: need to account for multiple resources and user predicate
+    return m_controller.deleteResources(resource.getResourceDefinition().getType(),
+        resource.getQuery().getPredicate());
+
+  }
+
+  protected Request createControllerRequest(Set<Map<String, Object>> setProperties) {
+    return PropertyHelper.getCreateRequest(setProperties);
+  }
+}

+ 35 - 9
ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java

@@ -18,19 +18,17 @@
 
 
 package org.apache.ambari.server.api.services.serializers;
 package org.apache.ambari.server.api.services.serializers;
 
 
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.codehaus.jackson.JsonFactory;
 import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.JsonGenerator;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.util.DefaultPrettyPrinter;
 import org.codehaus.jackson.util.DefaultPrettyPrinter;
 
 
-import javax.ws.rs.core.UriInfo;
 import java.io.*;
 import java.io.*;
 import java.nio.charset.Charset;
 import java.nio.charset.Charset;
-import java.util.Collection;
 import java.util.Map;
 import java.util.Map;
 
 
 /**
 /**
@@ -53,25 +51,53 @@ public class JsonSerializer implements ResultSerializer {
 
 
 
 
   @Override
   @Override
-  public Object serialize(Result result, UriInfo uriInfo) {
+  public Object serialize(Result result) {
     try {
     try {
-      ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
-      m_generator = createJsonGenerator(bytesOut);
+      ByteArrayOutputStream bytesOut = init();
 
 
-      DefaultPrettyPrinter p = new DefaultPrettyPrinter();
-      p.indentArraysWith(new DefaultPrettyPrinter.Lf2SpacesIndenter());
-      m_generator.setPrettyPrinter(p);
+      if (result.getStatus().isErrorState()) {
+        return serializeError(result.getStatus());
+      }
 
 
       processNode(result.getResultTree());
       processNode(result.getResultTree());
 
 
       m_generator.close();
       m_generator.close();
       return bytesOut.toString("UTF-8");
       return bytesOut.toString("UTF-8");
+    } catch (IOException e) {
+      //todo: exception handling.  Create ResultStatus 500 and call serializeError
+      throw new RuntimeException("Unable to serialize to json: " + e, e);
+    }
+  }
+
+  @Override
+  public Object serializeError(ResultStatus error) {
+    try {
+      ByteArrayOutputStream bytesOut = init();
+      //m_mapper.writeValue(m_generator, error);
+      m_generator.writeStartObject();
+      m_generator.writeNumberField("status", error.getStatus().getStatus());
+      m_generator.writeStringField("message", error.getMessage());
+      m_generator.writeEndObject();
+      m_generator.close();
+      return bytesOut.toString("UTF-8");
+
     } catch (IOException e) {
     } catch (IOException e) {
       //todo: exception handling
       //todo: exception handling
       throw new RuntimeException("Unable to serialize to json: " + e, e);
       throw new RuntimeException("Unable to serialize to json: " + e, e);
     }
     }
   }
   }
 
 
+  private ByteArrayOutputStream init() throws IOException {
+    ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+    m_generator = createJsonGenerator(bytesOut);
+
+    DefaultPrettyPrinter p = new DefaultPrettyPrinter();
+    p.indentArraysWith(new DefaultPrettyPrinter.Lf2SpacesIndenter());
+    m_generator.setPrettyPrinter(p);
+
+    return bytesOut;
+  }
+
   private void processNode(TreeNode<Resource> node) throws IOException {
   private void processNode(TreeNode<Resource> node) throws IOException {
     String name = node.getName();
     String name = node.getName();
     Resource r = node.getObject();
     Resource r = node.getObject();

+ 12 - 4
ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/ResultSerializer.java

@@ -19,10 +19,9 @@
 package org.apache.ambari.server.api.services.serializers;
 package org.apache.ambari.server.api.services.serializers;
 
 
 
 
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.Result;
 import org.apache.ambari.server.api.services.Result;
 
 
-import javax.ws.rs.core.UriInfo;
-
 /**
 /**
  * Format internal result to format expected by client.
  * Format internal result to format expected by client.
  */
  */
@@ -30,9 +29,18 @@ public interface ResultSerializer {
   /**
   /**
    * Serialize the given result to a format expected by client.
    * Serialize the given result to a format expected by client.
    *
    *
+   *
    * @param result  internal result
    * @param result  internal result
-   * @param uriInfo URL info for request
    * @return the serialized result
    * @return the serialized result
    */
    */
-  Object serialize(Result result, UriInfo uriInfo);
+  Object serialize(Result result);
+
+  /**
+   * Serialize an error result to the format expected by the client.
+   *
+   * @param error  the error result
+   *
+   * @return the serialized error result
+   */
+  Object serializeError(ResultStatus error);
 }
 }

+ 28 - 1
ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java

@@ -18,7 +18,9 @@
 
 
 package org.apache.ambari.server.bootstrap;
 package org.apache.ambari.server.bootstrap;
 
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
@@ -90,11 +92,36 @@ class BSHostStatusCollector {
         status.setLog("");
         status.setLog("");
       } else {
       } else {
         String logString = "";
         String logString = "";
+        BufferedReader reader = null;
         try {
         try {
-          logString = FileUtils.readFileToString(log);
+          StringBuilder sb = new StringBuilder();
+          reader = new BufferedReader(new FileReader(log));
+
+          String line = null;
+          while (null != (line = reader.readLine())) {
+            if (line.startsWith("tcgetattr:") || line.startsWith("tput:"))
+              continue;
+
+            if (0 != sb.length() || 0 == line.length())
+              sb.append('\n');
+
+            if (-1 != line.indexOf ("\\n"))
+              sb.append(line.replace("\\n", "\n"));
+            else
+              sb.append(line);
+          }
+          
+          logString = sb.toString();
         } catch (IOException e) {
         } catch (IOException e) {
           LOG.info("Error reading log file " + log);
           LOG.info("Error reading log file " + log);
         }
         }
+        finally {
+          try {
+            reader.close();
+          }
+          catch (Exception e) {
+          }
+        }
         status.setLog(logString);
         status.setLog(logString);
       }
       }
       hostStatus.add(status);
       hostStatus.add(status);

+ 9 - 1
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java

@@ -52,7 +52,7 @@ public class Configuration {
   public static final String BOOTSTRAP_SETUP_AGENT_PASSWORD = "bootstrap.setup_agent.password";
   public static final String BOOTSTRAP_SETUP_AGENT_PASSWORD = "bootstrap.setup_agent.password";
   public static final String BOOTSTRAP_MASTER_HOSTNAME = "bootstrap.master_host_name";
   public static final String BOOTSTRAP_MASTER_HOSTNAME = "bootstrap.master_host_name";
   public static final String API_AUTHENTICATE = "api.authenticate";
   public static final String API_AUTHENTICATE = "api.authenticate";
-
+  public static final String API_USE_SSL = "api.ssl";
   public static final String SRVR_KSTR_DIR_KEY = "security.server.keys_dir";
   public static final String SRVR_KSTR_DIR_KEY = "security.server.keys_dir";
   public static final String SRVR_CRT_NAME_KEY = "security.server.cert_name";
   public static final String SRVR_CRT_NAME_KEY = "security.server.cert_name";
   public static final String SRVR_KEY_NAME_KEY = "security.server.key_name";
   public static final String SRVR_KEY_NAME_KEY = "security.server.key_name";
@@ -305,6 +305,14 @@ public class Configuration {
     return ("true".equals(properties.getProperty(API_AUTHENTICATE, "false")));
     return ("true".equals(properties.getProperty(API_AUTHENTICATE, "false")));
   }
   }
 
 
+  /**
+   * Check to see if the API should be authenticated via ssl or not
+   * @return false if not, true if ssl needs to be used.
+   */
+  public boolean getApiSSLAuthentication() {
+    return ("true".equals(properties.getProperty(API_USE_SSL, "false")));
+  }
+
 
 
   public PersistenceType getPersistenceType() {
   public PersistenceType getPersistenceType() {
     String value = properties.getProperty(PERSISTENCE_IN_MEMORY_KEY, PERSISTENCE_IN_MEMORY_DEFAULT);
     String value = properties.getProperty(PERSISTENCE_IN_MEMORY_KEY, PERSISTENCE_IN_MEMORY_DEFAULT);

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

@@ -19,6 +19,8 @@
 package org.apache.ambari.server.controller;
 package org.apache.ambari.server.controller;
 
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.ParentObjectNotFoundException;
 
 
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
@@ -47,7 +49,7 @@ public interface AmbariManagementController {
    * @throws AmbariException thrown if the service cannot be created
    * @throws AmbariException thrown if the service cannot be created
    */
    */
   public void createServices(Set<ServiceRequest> requests)
   public void createServices(Set<ServiceRequest> requests)
-      throws AmbariException;
+      throws AmbariException, ParentObjectNotFoundException;
 
 
   /**
   /**
    * Create the component defined by the attributes in the given request object.
    * Create the component defined by the attributes in the given request object.

+ 331 - 135
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -19,26 +19,10 @@
 package org.apache.ambari.server.controller;
 package org.apache.ambari.server.controller;
 
 
 import java.net.InetAddress;
 import java.net.InetAddress;
-import java.util.ArrayList;
-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.*;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ClusterNotFoundException;
-import org.apache.ambari.server.HostNotFoundException;
-import org.apache.ambari.server.Role;
-import org.apache.ambari.server.RoleCommand;
-import org.apache.ambari.server.ServiceComponentHostNotFoundException;
-import org.apache.ambari.server.ServiceComponentNotFoundException;
-import org.apache.ambari.server.ServiceNotFoundException;
-import org.apache.ambari.server.StackNotFoundException;
+
+import org.apache.ambari.server.*;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.RequestStatus;
 import org.apache.ambari.server.actionmanager.RequestStatus;
@@ -258,7 +242,12 @@ public class AmbariManagementControllerImpl implements
         }
         }
       }
       }
 
 
-      Cluster cluster = clusters.getCluster(request.getClusterName());
+      Cluster cluster;
+      try {
+        cluster = clusters.getCluster(request.getClusterName());
+      } catch (ClusterNotFoundException e) {
+        throw new ParentObjectNotFoundException("Attempted to add a service to a cluster which doesn't exist", e);
+      }
       try {
       try {
         Service s = cluster.getService(request.getServiceName());
         Service s = cluster.getService(request.getServiceName());
         if (s != null) {
         if (s != null) {
@@ -298,9 +287,16 @@ public class AmbariManagementControllerImpl implements
         first = false;
         first = false;
         svcNames.append(svcName);
         svcNames.append(svcName);
       }
       }
-      throw new IllegalArgumentException("Invalid request"
-          + " contains duplicates within request or already existing services"
-          + ", duplicateServiceNames=" + svcNames.toString());
+      String clusterName = requests.iterator().next().getClusterName();
+      String msg;
+      if (duplicates.size() == 1) {
+        msg = "Attempted to create a service which already exists: "
+            + ", clusterName=" + clusterName  + " serviceName=" + svcNames.toString();
+      } else {
+        msg = "Attempted to create services which already exist: "
+            + ", clusterName=" + clusterName  + " serviceNames=" + svcNames.toString();
+      }
+      throw new DuplicateResourceException(msg);
     }
     }
 
 
     // now to the real work
     // now to the real work
@@ -349,7 +345,13 @@ public class AmbariManagementControllerImpl implements
             + " component");
             + " component");
       }
       }
 
 
-      Cluster cluster = clusters.getCluster(request.getClusterName());
+      Cluster cluster;
+      try {
+        cluster = clusters.getCluster(request.getClusterName());
+      } catch (ClusterNotFoundException e) {
+        throw new ParentObjectNotFoundException(
+            "Attempted to add a component to a cluster which doesn't exist:", e);
+      }
 
 
       if (request.getServiceName() == null
       if (request.getServiceName() == null
           || request.getServiceName().isEmpty()) {
           || request.getServiceName().isEmpty()) {
@@ -393,8 +395,8 @@ public class AmbariManagementControllerImpl implements
       if (componentNames.get(request.getClusterName())
       if (componentNames.get(request.getClusterName())
           .get(request.getServiceName()).contains(request.getComponentName())){
           .get(request.getServiceName()).contains(request.getComponentName())){
         // throw error later for dup
         // throw error later for dup
-        duplicates.add(request.getServiceName()
-            + "-" + request.getComponentName());
+        duplicates.add("[clusterName=" + request.getClusterName() + ", serviceName=" + request.getServiceName() +
+            ", componentName=" + request.getComponentName() + "]");
         continue;
         continue;
       }
       }
       componentNames.get(request.getClusterName())
       componentNames.get(request.getClusterName())
@@ -411,13 +413,19 @@ public class AmbariManagementControllerImpl implements
         }
         }
       }
       }
 
 
-      Service s = cluster.getService(request.getServiceName());
+      Service s;
+      try {
+        s = cluster.getService(request.getServiceName());
+      } catch (ServiceNotFoundException e) {
+        throw new ParentObjectNotFoundException(
+            "Attempted to add a component to a service which doesn't exist:", e);
+      }
       try {
       try {
         ServiceComponent sc = s.getServiceComponent(request.getComponentName());
         ServiceComponent sc = s.getServiceComponent(request.getComponentName());
         if (sc != null) {
         if (sc != null) {
           // throw error later for dup
           // throw error later for dup
-          duplicates.add(request.getServiceName()
-              + "-" + request.getComponentName());
+          duplicates.add("[clusterName=" + request.getClusterName() + ", serviceName=" + request.getServiceName() +
+              ", componentName=" + request.getComponentName() + "]");
           continue;
           continue;
         }
         }
       } catch (AmbariException e) {
       } catch (AmbariException e) {
@@ -453,10 +461,13 @@ public class AmbariManagementControllerImpl implements
         first = false;
         first = false;
         names.append(cName);
         names.append(cName);
       }
       }
-      throw new IllegalArgumentException("Invalid request"
-          + " contains duplicates within request or"
-          + " already existing service components"
-          + ", duplicateServiceComponentsNames=" + names.toString());
+      String msg;
+      if (duplicates.size() == 1) {
+        msg = "Attempted to create a component which already exists: ";
+      } else {
+        msg = "Attempted to create components which already exist: ";
+      }
+      throw new DuplicateResourceException(msg + names.toString());
     }
     }
 
 
 
 
@@ -529,17 +540,13 @@ public class AmbariManagementControllerImpl implements
         continue;
         continue;
       }
       }
 
 
-      if (request.getClusterNames() != null) {
-        for (String clusterName : request.getClusterNames()) {
-          try {
-            clusters.getCluster(clusterName);
-          } catch (ClusterNotFoundException e) {
-            // invalid cluster mapping
-            throw new IllegalArgumentException("Trying to map host"
-                + " to a non-existent cluster"
-                + ", hostname=" + request.getHostname()
-                + ", clusterName=" + clusterName);
-          }
+      if (request.getClusterName() != null) {
+        try {
+          // validate that cluster_name is valid
+          clusters.getCluster(request.getClusterName());
+        } catch (ClusterNotFoundException e) {
+          throw new ParentObjectNotFoundException("Attempted to add a host to a cluster which doesn't exist: "
+              + " clusterName=" + request.getClusterName());
         }
         }
       }
       }
     }
     }
@@ -569,23 +576,19 @@ public class AmbariManagementControllerImpl implements
         first = false;
         first = false;
         names.append(hName);
         names.append(hName);
       }
       }
-      // FIXME throw correct error
-      throw new AmbariException("Some hosts have not been registered with"
-          + " the server"
-          + ", hostnames=" + names.toString());
+
+      throw new IllegalArgumentException("Attempted to add unknown hosts to a cluster.  " +
+          "These hosts have not been registered with the server: " + names.toString());
     }
     }
 
 
     for (HostRequest request : requests) {
     for (HostRequest request : requests) {
-      Host h = clusters.getHost(request.getHostname());
-      if (request.getClusterNames() != null) {
-        for (String clusterName : request.getClusterNames()) {
-          clusters.mapHostToCluster(request.getHostname(), clusterName);
-        }
+      if (request.getClusterName() != null) {
+        clusters.mapHostToCluster(request.getHostname(), request.getClusterName());
       }
       }
 
 
       if (request.getHostAttributes() != null) {
       if (request.getHostAttributes() != null) {
-        h = clusters.getHost(request.getHostname());
-        h.setHostAttributes(request.getHostAttributes());
+        clusters.getHost(request.getHostname()).
+            setHostAttributes(request.getHostAttributes());
       }
       }
     }
     }
   }
   }
@@ -615,7 +618,13 @@ public class AmbariManagementControllerImpl implements
             + " when trying to create a hostcomponent");
             + " when trying to create a hostcomponent");
       }
       }
 
 
-      Cluster cluster = clusters.getCluster(request.getClusterName());
+      Cluster cluster;
+      try {
+        cluster = clusters.getCluster(request.getClusterName());
+      } catch (ClusterNotFoundException e) {
+        throw new ParentObjectNotFoundException(
+            "Attempted to add a host_component to a cluster which doesn't exist: ", e);
+      }
 
 
       if (request.getServiceName() == null
       if (request.getServiceName() == null
           || request.getServiceName().isEmpty()) {
           || request.getServiceName().isEmpty()) {
@@ -666,9 +675,8 @@ public class AmbariManagementControllerImpl implements
       if (hostComponentNames.get(request.getClusterName())
       if (hostComponentNames.get(request.getClusterName())
           .get(request.getServiceName()).get(request.getComponentName())
           .get(request.getServiceName()).get(request.getComponentName())
           .contains(request.getHostname())) {
           .contains(request.getHostname())) {
-        duplicates.add(request.getServiceName()
-            + "-" + request.getComponentName()
-            + "-" + request.getHostname());
+        duplicates.add("[clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname() +
+            ", componentName=" +request.getComponentName() +']');
         continue;
         continue;
       }
       }
       hostComponentNames.get(request.getClusterName())
       hostComponentNames.get(request.getClusterName())
@@ -686,10 +694,24 @@ public class AmbariManagementControllerImpl implements
         }
         }
       }
       }
 
 
-      Service s = cluster.getService(request.getServiceName());
+      Service s;
+      try {
+        s = cluster.getService(request.getServiceName());
+      } catch (ServiceNotFoundException e) {
+        throw new IllegalArgumentException(
+            "The service[" + request.getServiceName() + "] associated with the component[" +
+            request.getComponentName() + "] doesn't exist for the cluster[" + request.getClusterName() + "]");
+      }
       ServiceComponent sc = s.getServiceComponent(
       ServiceComponent sc = s.getServiceComponent(
           request.getComponentName());
           request.getComponentName());
-      Host host = clusters.getHost(request.getHostname());
+
+      Host host;
+      try {
+        host = clusters.getHost(request.getHostname());
+      } catch (HostNotFoundException e) {
+        throw new ParentObjectNotFoundException(
+            "Attempted to add a host_component to a host that doesn't exist: ", e);
+      }
       Set<Cluster> mappedClusters =
       Set<Cluster> mappedClusters =
           clusters.getClustersForHost(request.getHostname());
           clusters.getClustersForHost(request.getHostname());
       boolean validCluster = false;
       boolean validCluster = false;
@@ -713,21 +735,15 @@ public class AmbariManagementControllerImpl implements
         }
         }
       }
       }
       if (!validCluster) {
       if (!validCluster) {
-        // TODO fix throw correct error
-        throw new AmbariException("Invalid request as host does not belong to"
-            + " given cluster"
-            + ", clusterName=" + request.getClusterName()
-            + ", serviceName=" + request.getServiceName()
-            + ", componentName=" + request.getComponentName()
-            + ", hostname=" + request.getHostname());
+        throw new ParentObjectNotFoundException("Attempted to add a host_component to a host that doesn't exist: " +
+            "clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname());
       }
       }
       try {
       try {
         ServiceComponentHost sch = sc.getServiceComponentHost(
         ServiceComponentHost sch = sc.getServiceComponentHost(
             request.getHostname());
             request.getHostname());
         if (sch != null) {
         if (sch != null) {
-          duplicates.add(request.getServiceName()
-              + "-" + request.getComponentName()
-              + "-" + request.getHostname());
+          duplicates.add("[clusterName=" + request.getClusterName() + ", hostName=" + request.getHostname() +
+              ", componentName=" +request.getComponentName() +']');
           continue;
           continue;
         }
         }
       } catch (AmbariException e) {
       } catch (AmbariException e) {
@@ -751,10 +767,13 @@ public class AmbariManagementControllerImpl implements
         first = false;
         first = false;
         names.append(hName);
         names.append(hName);
       }
       }
-      throw new IllegalArgumentException("Invalid request"
-          + " contains duplicates within request or"
-          + " already existing host components"
-          + ", duplicateServiceComponentHostNames=" + names.toString());
+      String msg;
+      if (duplicates.size() == 1) {
+        msg = "Attempted to create a host_component which already exists: ";
+      } else {
+        msg = "Attempted to create host_component's which already exist: ";
+      }
+      throw new DuplicateResourceException(msg + names.toString());
     }
     }
 
 
     // now doing actual work
     // now doing actual work
@@ -778,9 +797,7 @@ public class AmbariManagementControllerImpl implements
           && !request.getDesiredState().isEmpty()) {
           && !request.getDesiredState().isEmpty()) {
         State state = State.valueOf(request.getDesiredState());
         State state = State.valueOf(request.getDesiredState());
         sch.setDesiredState(state);
         sch.setDesiredState(state);
-      } else {
-        sch.setDesiredState(sc.getDesiredState());
-      }
+      } 
 
 
       sch.setDesiredStackVersion(sc.getDesiredStackVersion());
       sch.setDesiredStackVersion(sc.getDesiredStackVersion());
 
 
@@ -923,6 +940,7 @@ public class AmbariManagementControllerImpl implements
 
 
   private synchronized Set<ClusterResponse> getClusters(ClusterRequest request)
   private synchronized Set<ClusterResponse> getClusters(ClusterRequest request)
       throws AmbariException {
       throws AmbariException {
+
     Set<ClusterResponse> response = new HashSet<ClusterResponse>();
     Set<ClusterResponse> response = new HashSet<ClusterResponse>();
 
 
     if (LOG.isDebugEnabled()) {
     if (LOG.isDebugEnabled()) {
@@ -968,7 +986,13 @@ public class AmbariManagementControllerImpl implements
       throw new AmbariException("Invalid arguments, cluster name"
       throw new AmbariException("Invalid arguments, cluster name"
           + " cannot be null");
           + " cannot be null");
     }
     }
-    final Cluster cluster = clusters.getCluster(request.getClusterName());
+    String clusterName = request.getClusterName();
+    final Cluster cluster;
+    try {
+      cluster = clusters.getCluster(clusterName);
+    } catch (ObjectNotFoundException e) {
+      throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
+    }
 
 
     Set<ServiceResponse> response = new HashSet<ServiceResponse>();
     Set<ServiceResponse> response = new HashSet<ServiceResponse>();
     if (request.getServiceName() != null) {
     if (request.getServiceName() != null) {
@@ -1011,7 +1035,12 @@ public class AmbariManagementControllerImpl implements
           + " should be non-null");
           + " should be non-null");
     }
     }
 
 
-    final Cluster cluster = clusters.getCluster(request.getClusterName());
+    final Cluster cluster;
+    try {
+      cluster = clusters.getCluster(request.getClusterName());
+    } catch (ObjectNotFoundException e) {
+      throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
+    }
 
 
     Set<ServiceComponentResponse> response =
     Set<ServiceComponentResponse> response =
         new HashSet<ServiceComponentResponse>();
         new HashSet<ServiceComponentResponse>();
@@ -1036,7 +1065,14 @@ public class AmbariManagementControllerImpl implements
         }
         }
         request.setServiceName(serviceName);
         request.setServiceName(serviceName);
       }
       }
-      Service s = cluster.getService(request.getServiceName());
+
+      final Service s;
+      try {
+        s = cluster.getService(request.getServiceName());
+      } catch (ObjectNotFoundException e) {
+        throw new ParentObjectNotFoundException("Parent Service resource doesn't exist", e);
+      }
+
       ServiceComponent sc = s.getServiceComponent(request.getComponentName());
       ServiceComponent sc = s.getServiceComponent(request.getComponentName());
       response.add(sc.convertToResponse());
       response.add(sc.convertToResponse());
       return response;
       return response;
@@ -1078,28 +1114,52 @@ public class AmbariManagementControllerImpl implements
 
 
   private synchronized Set<HostResponse> getHosts(HostRequest request)
   private synchronized Set<HostResponse> getHosts(HostRequest request)
       throws AmbariException {
       throws AmbariException {
+
+    //TODO/FIXME host can only belong to a single cluster so get host directly from Cluster
+    //TODO/FIXME what is the requirement for filtering on host attributes?
+
+    List<Host>        hosts;
     Set<HostResponse> response = new HashSet<HostResponse>();
     Set<HostResponse> response = new HashSet<HostResponse>();
+    Cluster           cluster  = null;
 
 
-    // FIXME what is the requirement for filtering on host attributes?
-    // FIXME do we need get all hosts in given list of clusters?
+    String clusterName = request.getClusterName();
+    String hostName    = request.getHostname();
 
 
-    List<Host> hosts = null;
-    if (request.getHostname() != null) {
-      Host h = clusters.getHost(request.getHostname());
-      hosts = new ArrayList<Host>();
-      hosts.add(h);
-    } else {
+    if (clusterName != null) {
+      //validate that cluster exists, throws exception if it doesn't.
+      try {
+        cluster = clusters.getCluster(clusterName);
+      } catch (ObjectNotFoundException e) {
+        throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
+      }
+    }
+
+    if (hostName == null) {
       hosts = clusters.getHosts();
       hosts = clusters.getHosts();
+    } else {
+      hosts = new ArrayList<Host>();
+      hosts.add(clusters.getHost(request.getHostname()));
     }
     }
 
 
     for (Host h : hosts) {
     for (Host h : hosts) {
-      HostResponse r = h.convertToResponse();
-      Set<Cluster> cs =
-          clusters.getClustersForHost(h.getHostName());
-      for (Cluster c : cs) {
-        r.getClusterNames().add(c.getClusterName());
+      if (clusterName != null) {
+        if (clusters.getClustersForHost(h.getHostName()).contains(cluster)) {
+          HostResponse r = h.convertToResponse();
+          r.setClusterName(clusterName);
+          response.add(r);
+        } else if (hostName != null) {
+          throw new HostNotFoundException(hostName);
+        }
+      } else {
+        HostResponse r = h.convertToResponse();
+
+        Set<Cluster> clustersForHost = clusters.getClustersForHost(h.getHostName());
+        //todo: host can only belong to a single cluster
+        if (clustersForHost != null && clustersForHost.size() != 0) {
+          r.setClusterName(clustersForHost.iterator().next().getClusterName());
+        }
+        response.add(r);
       }
       }
-      response.add(r);
     }
     }
     return response;
     return response;
   }
   }
@@ -1108,11 +1168,29 @@ public class AmbariManagementControllerImpl implements
       ServiceComponentHostRequest request) throws AmbariException {
       ServiceComponentHostRequest request) throws AmbariException {
     if (request.getClusterName() == null
     if (request.getClusterName() == null
         || request.getClusterName().isEmpty()) {
         || request.getClusterName().isEmpty()) {
-      throw new AmbariException("Invalid arguments, cluster name should not"
-          + " be null");
+      throw new IllegalArgumentException("Invalid arguments, cluster name should not be null");
+    }
+
+    final Cluster cluster;
+    try {
+      cluster = clusters.getCluster(request.getClusterName());
+    } catch (ClusterNotFoundException e) {
+      throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
     }
     }
 
 
-    final Cluster cluster = clusters.getCluster(request.getClusterName());
+    if (request.getHostname() != null) {
+      try {
+        if (! clusters.getClustersForHost(request.getHostname()).contains(cluster)) {
+          // case where host exists but not associated with given cluster
+          throw new ParentObjectNotFoundException("Parent Host resource doesn't exist",
+              new HostNotFoundException(request.getClusterName(), request.getHostname()));
+        }
+      } catch (HostNotFoundException e) {
+        // creating new HostNotFoundException to add cluster name
+        throw new ParentObjectNotFoundException("Parent Host resource doesn't exist",
+            new HostNotFoundException(request.getClusterName(), request.getHostname()));
+      }
+    }
 
 
     if (request.getComponentName() != null) {
     if (request.getComponentName() != null) {
       if (request.getServiceName() == null
       if (request.getServiceName() == null
@@ -1124,22 +1202,20 @@ public class AmbariManagementControllerImpl implements
         if (LOG.isDebugEnabled()) {
         if (LOG.isDebugEnabled()) {
           LOG.debug("Looking up service name for component"
           LOG.debug("Looking up service name for component"
               + ", componentName=" + request.getComponentName()
               + ", componentName=" + request.getComponentName()
-              + ", serviceName=" + serviceName);
+              + ", serviceName=" + serviceName
+              + ", stackInfo=" + stackId.getStackId());
         }
         }
         if (serviceName == null
         if (serviceName == null
             || serviceName.isEmpty()) {
             || serviceName.isEmpty()) {
-          throw new AmbariException("Could not find service for component"
-              + ", componentName=" + request.getComponentName()
-              + ", clusterName=" + cluster.getClusterName()
-              + ", stackInfo=" + stackId.getStackId());
+          throw new ServiceComponentHostNotFoundException(
+              cluster.getClusterName(), null, request.getComponentName(),request.getHostname());
         }
         }
         request.setServiceName(serviceName);
         request.setServiceName(serviceName);
       }
       }
     }
     }
 
 
     Set<Service> services = new HashSet<Service>();
     Set<Service> services = new HashSet<Service>();
-    if (request.getServiceName() != null
-        && !request.getServiceName().isEmpty()) {
+    if (request.getServiceName() != null && !request.getServiceName().isEmpty()) {
       services.add(cluster.getService(request.getServiceName()));
       services.add(cluster.getService(request.getServiceName()));
     } else {
     } else {
       services.addAll(cluster.getServices().values());
       services.addAll(cluster.getServices().values());
@@ -1189,8 +1265,15 @@ public class AmbariManagementControllerImpl implements
             ServiceComponentHostResponse r = sch.convertToResponse();
             ServiceComponentHostResponse r = sch.convertToResponse();
             response.add(r);
             response.add(r);
           } catch (ServiceComponentHostNotFoundException e) {
           } catch (ServiceComponentHostNotFoundException e) {
-            // Expected
-            // ignore and continue
+            if (request.getServiceName() != null && request.getComponentName() != null) {
+              throw new ServiceComponentHostNotFoundException(cluster.getClusterName(),
+                  request.getServiceName(), request.getComponentName(),request.getHostname());
+            } else {
+              // ignore this since host_component was not specified
+              // this is an artifact of how we get host_components and can happen
+              // in case where we get all host_components for a host
+            }
+
           }
           }
         } else {
         } else {
           for (ServiceComponentHost sch :
           for (ServiceComponentHost sch :
@@ -1434,6 +1517,7 @@ public class AmbariManagementControllerImpl implements
                 if (oldSchState == State.INIT
                 if (oldSchState == State.INIT
                     || oldSchState == State.UNINSTALLED
                     || oldSchState == State.UNINSTALLED
                     || oldSchState == State.INSTALLED
                     || oldSchState == State.INSTALLED
+                    || oldSchState == State.INSTALLING
                     || oldSchState == State.INSTALL_FAILED) {
                     || oldSchState == State.INSTALL_FAILED) {
                   roleCommand = RoleCommand.INSTALL;
                   roleCommand = RoleCommand.INSTALL;
                   event = new ServiceComponentHostInstallEvent(
                   event = new ServiceComponentHostInstallEvent(
@@ -1461,14 +1545,18 @@ public class AmbariManagementControllerImpl implements
                 }
                 }
                 break;
                 break;
               case STARTED:
               case STARTED:
+                StackId stackId = scHost.getDesiredStackVersion();
+                ComponentInfo compInfo = ambariMetaInfo.getComponentCategory(
+                    stackId.getStackName(), stackId.getStackVersion(), scHost.getServiceName(),
+                    scHost.getServiceComponentName());
                 if (oldSchState == State.INSTALLED
                 if (oldSchState == State.INSTALLED
-                    || oldSchState == State.START_FAILED) {
+                    || oldSchState == State.START_FAILED || oldSchState == State.STARTING) {
                   roleCommand = RoleCommand.START;
                   roleCommand = RoleCommand.START;
                   event = new ServiceComponentHostStartEvent(
                   event = new ServiceComponentHostStartEvent(
                       scHost.getServiceComponentName(), scHost.getHostName(),
                       scHost.getServiceComponentName(), scHost.getHostName(),
                       nowTimestamp, scHost.getDesiredConfigVersionsRecursive());
                       nowTimestamp, scHost.getDesiredConfigVersionsRecursive());
                 } else {
                 } else {
-                  throw new AmbariException("Invalid transition for"
+                  String error = "Invalid transition for"
                       + " servicecomponenthost"
                       + " servicecomponenthost"
                       + ", clusterName=" + cluster.getClusterName()
                       + ", clusterName=" + cluster.getClusterName()
                       + ", clusterId=" + cluster.getClusterId()
                       + ", clusterId=" + cluster.getClusterId()
@@ -1476,7 +1564,13 @@ public class AmbariManagementControllerImpl implements
                       + ", componentName=" + scHost.getServiceComponentName()
                       + ", componentName=" + scHost.getServiceComponentName()
                       + ", hostname=" + scHost.getHostName()
                       + ", hostname=" + scHost.getHostName()
                       + ", currentState=" + oldSchState
                       + ", currentState=" + oldSchState
-                      + ", newDesiredState=" + newState);
+                      + ", newDesiredState=" + newState;
+                  if (compInfo.isMaster()) {
+                    throw new AmbariException(error);
+                  } else {
+                    LOG.info("Ignoring: " + error);
+                    continue;
+                  }
                 }
                 }
                 break;
                 break;
               case UNINSTALLED:
               case UNINSTALLED:
@@ -1577,7 +1671,6 @@ public class AmbariManagementControllerImpl implements
             new ServiceComponentHostOpInProgressEvent(null, clientHost,
             new ServiceComponentHostOpInProgressEvent(null, clientHost,
                 nowTimestamp), cluster.getClusterName(), serviceName);
                 nowTimestamp), cluster.getClusterName(), serviceName);
 
 
-
         Map<String, Map<String, String>> configurations =
         Map<String, Map<String, String>> configurations =
             new TreeMap<String, Map<String, String>>();
             new TreeMap<String, Map<String, String>>();
         Map<String, Config> allConfigs = cluster.getService(serviceName).getDesiredConfigs();
         Map<String, Config> allConfigs = cluster.getService(serviceName).getDesiredConfigs();
@@ -1591,6 +1684,10 @@ public class AmbariManagementControllerImpl implements
             smokeTestRole).getExecutionCommand()
             smokeTestRole).getExecutionCommand()
             .setConfigurations(configurations);
             .setConfigurations(configurations);
 
 
+        // Generate cluster host info
+        stage.getExecutionCommandWrapper(clientHost, smokeTestRole)
+            .getExecutionCommand()
+            .setClusterHostInfo(StageUtils.getClusterHostInfo(cluster));
       }
       }
 
 
       RoleGraph rg = new RoleGraph(rco);
       RoleGraph rg = new RoleGraph(rco);
@@ -1654,6 +1751,7 @@ public class AmbariManagementControllerImpl implements
         if (oldState == State.INIT
         if (oldState == State.INIT
             || oldState == State.UNINSTALLED
             || oldState == State.UNINSTALLED
             || oldState == State.INSTALLED
             || oldState == State.INSTALLED
+            || oldState == State.INSTALLING
             || oldState == State.STARTED
             || oldState == State.STARTED
             || oldState == State.START_FAILED
             || oldState == State.START_FAILED
             || oldState == State.INSTALL_FAILED
             || oldState == State.INSTALL_FAILED
@@ -1663,6 +1761,7 @@ public class AmbariManagementControllerImpl implements
         break;
         break;
       case STARTED:
       case STARTED:
         if (oldState == State.INSTALLED
         if (oldState == State.INSTALLED
+            || oldState == State.STARTING
             || oldState == State.STARTED
             || oldState == State.STARTED
             || oldState == State.START_FAILED) {
             || oldState == State.START_FAILED) {
           return true;
           return true;
@@ -2296,8 +2395,14 @@ public class AmbariManagementControllerImpl implements
 
 
       Host h = clusters.getHost(request.getHostname());
       Host h = clusters.getHost(request.getHostname());
 
 
-      for (String clusterName : request.getClusterNames()) {
-        clusters.mapHostToCluster(request.getHostname(), clusterName);
+      try {
+        //todo: the below method throws an exception when trying to create a duplicate mapping.
+        //todo: this is done to detect duplicates during host create.  Unless it is allowable to
+        //todo: add a host to a cluster by modifying the cluster_name prop, we should not do this mapping here.
+        //todo: Determine if it is allowable to associate a host to a cluster via this mechanism.
+        clusters.mapHostToCluster(request.getHostname(), request.getClusterName());
+      } catch (DuplicateResourceException e) {
+        // do nothing
       }
       }
 
 
       if (null != request.getHostAttributes())
       if (null != request.getHostAttributes())
@@ -2310,8 +2415,10 @@ public class AmbariManagementControllerImpl implements
       if (null != request.getPublicHostName()) {
       if (null != request.getPublicHostName()) {
         h.setPublicHostName(request.getPublicHostName());
         h.setPublicHostName(request.getPublicHostName());
       }
       }
-    }
 
 
+      //todo: if attempt was made to update a property other than those
+      //todo: that are allowed above, should throw exception
+    }
   }
   }
 
 
   @Override
   @Override
@@ -2479,8 +2586,8 @@ public class AmbariManagementControllerImpl implements
               + ", newDesiredState=" + newState);
               + ", newDesiredState=" + newState);
         }
         }
         continue;
         continue;
-      }
-
+      } 
+      
       if (!isValidStateTransition(oldSchState, newState)) {
       if (!isValidStateTransition(oldSchState, newState)) {
         throw new AmbariException("Invalid transition for"
         throw new AmbariException("Invalid transition for"
             + " servicecomponenthost"
             + " servicecomponenthost"
@@ -2599,14 +2706,12 @@ public class AmbariManagementControllerImpl implements
   @Override
   @Override
   public RequestStatusResponse deleteServices(Set<ServiceRequest> request)
   public RequestStatusResponse deleteServices(Set<ServiceRequest> request)
       throws AmbariException {
       throws AmbariException {
-    // TODO Auto-generated method stub
     throw new AmbariException("Delete services not supported");
     throw new AmbariException("Delete services not supported");
   }
   }
 
 
   @Override
   @Override
   public RequestStatusResponse deleteComponents(
   public RequestStatusResponse deleteComponents(
       Set<ServiceComponentRequest> request) throws AmbariException {
       Set<ServiceComponentRequest> request) throws AmbariException {
-    // TODO Auto-generated method stub
     throw new AmbariException("Delete components not supported");
     throw new AmbariException("Delete components not supported");
   }
   }
 
 
@@ -2619,7 +2724,6 @@ public class AmbariManagementControllerImpl implements
   @Override
   @Override
   public RequestStatusResponse deleteHostComponents(
   public RequestStatusResponse deleteHostComponents(
       Set<ServiceComponentHostRequest> request) throws AmbariException {
       Set<ServiceComponentHostRequest> request) throws AmbariException {
-    // TODO Auto-generated method stub
     throw new AmbariException("Delete host components not supported");
     throw new AmbariException("Delete host components not supported");
   }
   }
 
 
@@ -2666,7 +2770,7 @@ public class AmbariManagementControllerImpl implements
 
 
   public Set<RequestStatusResponse> getRequestsByStatus(RequestsByStatusesRequest request) {
   public Set<RequestStatusResponse> getRequestsByStatus(RequestsByStatusesRequest request) {
 
 
-    //TODO implement
+    //TODO implement.  Throw UnsupportedOperationException if it is not supported.
     return Collections.emptySet();
     return Collections.emptySet();
   }
   }
 
 
@@ -2703,8 +2807,17 @@ public class AmbariManagementControllerImpl implements
         response.add(getRequestStatusResponse(requestId.longValue()));
         response.add(getRequestStatusResponse(requestId.longValue()));
       }
       }
     } else {
     } else {
-      response.add(getRequestStatusResponse(
-          request.getRequestId().longValue()));
+      RequestStatusResponse requestStatusResponse = getRequestStatusResponse(
+          request.getRequestId().longValue());
+
+      //todo: correlate request with cluster
+      if (requestStatusResponse.getTasks().size() == 0) {
+        //todo: should be thrown lower in stack but we only want to throw if id was specified
+        //todo: and we currently iterate over all id's and invoke for each if id is not specified
+        throw new ObjectNotFoundException("Request resource doesn't exist.");
+      } else {
+        response.add(requestStatusResponse);
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2733,11 +2846,18 @@ public class AmbariManagementControllerImpl implements
   }
   }
 
 
   @Override
   @Override
-  public Set<ClusterResponse> getClusters(Set<ClusterRequest> requests)
-      throws AmbariException {
+  public Set<ClusterResponse> getClusters(Set<ClusterRequest> requests) throws AmbariException {
     Set<ClusterResponse> response = new HashSet<ClusterResponse>();
     Set<ClusterResponse> response = new HashSet<ClusterResponse>();
     for (ClusterRequest request : requests) {
     for (ClusterRequest request : requests) {
-      response.addAll(getClusters(request));
+      try {
+        response.addAll(getClusters(request));
+      } catch (ClusterNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2747,7 +2867,15 @@ public class AmbariManagementControllerImpl implements
       throws AmbariException {
       throws AmbariException {
     Set<ServiceResponse> response = new HashSet<ServiceResponse>();
     Set<ServiceResponse> response = new HashSet<ServiceResponse>();
     for (ServiceRequest request : requests) {
     for (ServiceRequest request : requests) {
-      response.addAll(getServices(request));
+      try {
+        response.addAll(getServices(request));
+      } catch (ServiceNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2758,7 +2886,15 @@ public class AmbariManagementControllerImpl implements
     Set<ServiceComponentResponse> response =
     Set<ServiceComponentResponse> response =
         new HashSet<ServiceComponentResponse>();
         new HashSet<ServiceComponentResponse>();
     for (ServiceComponentRequest request : requests) {
     for (ServiceComponentRequest request : requests) {
-      response.addAll(getComponents(request));
+      try {
+        response.addAll(getComponents(request));
+      } catch (ServiceComponentNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2768,7 +2904,15 @@ public class AmbariManagementControllerImpl implements
       throws AmbariException {
       throws AmbariException {
     Set<HostResponse> response = new HashSet<HostResponse>();
     Set<HostResponse> response = new HashSet<HostResponse>();
     for (HostRequest request : requests) {
     for (HostRequest request : requests) {
-      response.addAll(getHosts(request));
+      try {
+        response.addAll(getHosts(request));
+      } catch (HostNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2779,7 +2923,48 @@ public class AmbariManagementControllerImpl implements
     Set<ServiceComponentHostResponse> response =
     Set<ServiceComponentHostResponse> response =
         new HashSet<ServiceComponentHostResponse>();
         new HashSet<ServiceComponentHostResponse>();
     for (ServiceComponentHostRequest request : requests) {
     for (ServiceComponentHostRequest request : requests) {
-      response.addAll(getHostComponents(request));
+      try {
+        response.addAll(getHostComponents(request));
+      } catch (ServiceComponentHostNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          throw e;
+        }
+      } catch (ServiceNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          // In 'OR' case, a host_component may be included in predicate
+          // that has no corresponding service
+          throw e;
+        }
+      } catch (ServiceComponentNotFoundException e) {
+        if (requests.size() == 1) {
+          // only throw exception if 1 request.
+          // there will be > 1 request in case of OR predicate
+          // In 'OR' case, a host_component may be included in predicate
+          // that has no corresponding component
+          throw e;
+        }
+      } catch (ParentObjectNotFoundException e) {
+        // If there is only one request, always throw exception.
+        // There will be > 1 request in case of OR predicate.
+
+        // For HostNotFoundException, only throw exception if host_name is
+        // provided in URL.  If host_name is part of query, don't throw exception.
+        boolean throwException = true;
+        if (requests.size() > 1 && HostNotFoundException.class.isInstance(e.getCause())) {
+          for (ServiceComponentHostRequest r : requests) {
+            if (r.getHostname() == null) {
+              // host_name provided in query since all requests don't have host_name set
+              throwException = false;
+              break;
+            }
+          }
+        }
+        if (throwException) throw e;
+      }
     }
     }
     return response;
     return response;
   }
   }
@@ -2818,12 +3003,17 @@ public class AmbariManagementControllerImpl implements
 
 
         User u = users.getAnyUser(r.getUsername());
         User u = users.getAnyUser(r.getUsername());
         if (null == u) {
         if (null == u) {
-          throw new AmbariException("Cannot find user '"
-              + r.getUsername() + "'");
+          if (requests.size() == 1) {
+            // only throw exceptin if there is a single request
+            // if there are multiple requests, this indicates an OR predicate
+            throw new ObjectNotFoundException("Cannot find user '"
+                + r.getUsername() + "'");
+          }
+        } else {
+          UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser());
+          resp.setRoles(new HashSet<String>(u.getRoles()));
+          responses.add(resp);
         }
         }
-        UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser());
-        resp.setRoles(new HashSet<String>(u.getRoles()));
-        responses.add(resp);
       }
       }
     }
     }
 
 
@@ -2933,7 +3123,6 @@ public class AmbariManagementControllerImpl implements
 
 
     stage.getExecutionCommandWrapper(hostName, actionRequest.getActionName()).getExecutionCommand()
     stage.getExecutionCommandWrapper(hostName, actionRequest.getActionName()).getExecutionCommand()
         .setRoleParams(actionRequest.getParameters());
         .setRoleParams(actionRequest.getParameters());
-    
 
 
     Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
     Map<String, Map<String, String>> configurations = new TreeMap<String, Map<String, String>>();
     Map<String, Config> allConfigs = clusters.getCluster(clusterName)
     Map<String, Config> allConfigs = clusters.getCluster(clusterName)
@@ -2947,6 +3136,13 @@ public class AmbariManagementControllerImpl implements
     stage.getExecutionCommandWrapper(hostName,
     stage.getExecutionCommandWrapper(hostName,
         actionRequest.getActionName()).getExecutionCommand()
         actionRequest.getActionName()).getExecutionCommand()
         .setConfigurations(configurations); 
         .setConfigurations(configurations); 
+    
+    // Generate cluster host info
+    stage
+        .getExecutionCommandWrapper(hostName, actionRequest.getActionName())
+        .getExecutionCommand()
+        .setClusterHostInfo(
+            StageUtils.getClusterHostInfo(clusters.getCluster(clusterName)));
   }
   }
 
 
   private void addDecommissionDatanodeAction(
   private void addDecommissionDatanodeAction(

+ 70 - 52
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

@@ -1,20 +1,20 @@
 /**
 /**
-* 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.
-*/
+ * 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;
 package org.apache.ambari.server.controller;
 
 
@@ -71,10 +71,11 @@ import com.sun.jersey.spi.container.servlet.ServletContainer;
 @Singleton
 @Singleton
 public class AmbariServer {
 public class AmbariServer {
   private static Logger LOG = LoggerFactory.getLogger(AmbariServer.class);
   private static Logger LOG = LoggerFactory.getLogger(AmbariServer.class);
-  public static final int AGENT_ONE_WAY_AUTH = 4080;
-  public static final int AGENT_TWO_WAY_AUTH = 8443;
+  public static final int AGENT_ONE_WAY_AUTH = 8440;
+  public static final int AGENT_TWO_WAY_AUTH = 8441;
+  public static final int CLIENT_SSL_API_PORT = 8443;
   public static final int CLIENT_API_PORT = 8080;
   public static final int CLIENT_API_PORT = 8080;
- 
+
   private Server server = null;
   private Server server = null;
   private Server serverForAgent = null;
   private Server serverForAgent = null;
 
 
@@ -132,8 +133,8 @@ public class AmbariServer {
       String[] contextLocations = {SPRING_CONTEXT_LOCATION};
       String[] contextLocations = {SPRING_CONTEXT_LOCATION};
       ClassPathXmlApplicationContext springAppContext = new
       ClassPathXmlApplicationContext springAppContext = new
           ClassPathXmlApplicationContext(contextLocations, parentSpringAppContext);
           ClassPathXmlApplicationContext(contextLocations, parentSpringAppContext);
-       //setting ambari web context
- 
+      //setting ambari web context
+
       ServletContextHandler root = new ServletContextHandler(server, CONTEXT_PATH, 
       ServletContextHandler root = new ServletContextHandler(server, CONTEXT_PATH, 
           ServletContextHandler.NO_SECURITY | ServletContextHandler.SECURITY |
           ServletContextHandler.NO_SECURITY | ServletContextHandler.SECURITY |
           ServletContextHandler.SECURITY | ServletContextHandler.SESSIONS);
           ServletContextHandler.SECURITY | ServletContextHandler.SESSIONS);
@@ -143,7 +144,7 @@ public class AmbariServer {
       springWebAppContext.setParent(springAppContext);
       springWebAppContext.setParent(springAppContext);
       /* Configure web app context */
       /* Configure web app context */
       root.setResourceBase(configs.getWebAppDir());
       root.setResourceBase(configs.getWebAppDir());
-      
+
       root.getServletContext().setAttribute(
       root.getServletContext().setAttribute(
           WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
           WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
           springWebAppContext);
           springWebAppContext);
@@ -167,11 +168,11 @@ public class AmbariServer {
       if (configs.getApiAuthentication()) {
       if (configs.getApiAuthentication()) {
         root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", 1);
         root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", 1);
       }
       }
-      
-      
+
+
       //Secured connector for 2-way auth
       //Secured connector for 2-way auth
       SslSelectChannelConnector sslConnectorTwoWay = new  
       SslSelectChannelConnector sslConnectorTwoWay = new  
-            SslSelectChannelConnector();
+          SslSelectChannelConnector();
       sslConnectorTwoWay.setPort(AGENT_TWO_WAY_AUTH);
       sslConnectorTwoWay.setPort(AGENT_TWO_WAY_AUTH);
 
 
       Map<String, String> configsMap = configs.getConfigsMap();
       Map<String, String> configsMap = configs.getConfigsMap();
@@ -186,7 +187,7 @@ public class AmbariServer {
       sslConnectorTwoWay.setKeystoreType("PKCS12");
       sslConnectorTwoWay.setKeystoreType("PKCS12");
       sslConnectorTwoWay.setTruststoreType("PKCS12");
       sslConnectorTwoWay.setTruststoreType("PKCS12");
       sslConnectorTwoWay.setNeedClientAuth(true);
       sslConnectorTwoWay.setNeedClientAuth(true);
-      
+
       //Secured connector for 1-way auth
       //Secured connector for 1-way auth
       //SslSelectChannelConnector sslConnectorOneWay = new SslSelectChannelConnector();
       //SslSelectChannelConnector sslConnectorOneWay = new SslSelectChannelConnector();
       SslContextFactory contextFactory = new SslContextFactory(true);
       SslContextFactory contextFactory = new SslContextFactory(true);
@@ -197,42 +198,42 @@ public class AmbariServer {
       // sslConnectorOneWay.setTruststore(keystore);
       // sslConnectorOneWay.setTruststore(keystore);
       contextFactory.setKeyStorePassword(srvrCrtPass);
       contextFactory.setKeyStorePassword(srvrCrtPass);
       // sslConnectorOneWay.setPassword(srvrCrtPass);
       // sslConnectorOneWay.setPassword(srvrCrtPass);
-      
+
       contextFactory.setKeyManagerPassword(srvrCrtPass);
       contextFactory.setKeyManagerPassword(srvrCrtPass);
 
 
       // sslConnectorOneWay.setKeyPassword(srvrCrtPass);
       // sslConnectorOneWay.setKeyPassword(srvrCrtPass);
-      
+
       contextFactory.setTrustStorePassword(srvrCrtPass);
       contextFactory.setTrustStorePassword(srvrCrtPass);
       //sslConnectorOneWay.setTrustPassword(srvrCrtPass);
       //sslConnectorOneWay.setTrustPassword(srvrCrtPass);
-      
+
       contextFactory.setKeyStoreType("PKCS12");
       contextFactory.setKeyStoreType("PKCS12");
       //sslConnectorOneWay.setKeystoreType("PKCS12");
       //sslConnectorOneWay.setKeystoreType("PKCS12");
       contextFactory.setTrustStoreType("PKCS12");
       contextFactory.setTrustStoreType("PKCS12");
-     
+
       //sslConnectorOneWay.setTruststoreType("PKCS12");
       //sslConnectorOneWay.setTruststoreType("PKCS12");
       contextFactory.setNeedClientAuth(false);
       contextFactory.setNeedClientAuth(false);
       // sslConnectorOneWay.setWantClientAuth(false);
       // sslConnectorOneWay.setWantClientAuth(false);
       // sslConnectorOneWay.setNeedClientAuth(false);
       // sslConnectorOneWay.setNeedClientAuth(false);
       SslSelectChannelConnector sslConnectorOneWay = new SslSelectChannelConnector(contextFactory);
       SslSelectChannelConnector sslConnectorOneWay = new SslSelectChannelConnector(contextFactory);
       sslConnectorOneWay.setPort(AGENT_ONE_WAY_AUTH);
       sslConnectorOneWay.setPort(AGENT_ONE_WAY_AUTH);
-      
+
       serverForAgent.setConnectors(new Connector[]{ sslConnectorOneWay, sslConnectorTwoWay});
       serverForAgent.setConnectors(new Connector[]{ sslConnectorOneWay, sslConnectorTwoWay});
-      
+
       ServletHolder sh = new ServletHolder(ServletContainer.class);
       ServletHolder sh = new ServletHolder(ServletContainer.class);
       sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
       sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
-              "com.sun.jersey.api.core.PackagesResourceConfig");
+          "com.sun.jersey.api.core.PackagesResourceConfig");
       sh.setInitParameter("com.sun.jersey.config.property.packages",
       sh.setInitParameter("com.sun.jersey.config.property.packages",
-              "org.apache.ambari.server.api.rest;" +
+          "org.apache.ambari.server.api.rest;" +
               "org.apache.ambari.server.api.services;" +
               "org.apache.ambari.server.api.services;" +
-              "org.apache.ambari.eventdb.webservice");
+          "org.apache.ambari.eventdb.webservice");
       root.addServlet(sh, "/api/v1/*");
       root.addServlet(sh, "/api/v1/*");
       sh.setInitOrder(2);
       sh.setInitOrder(2);
-      
+
       ServletHolder agent = new ServletHolder(ServletContainer.class);
       ServletHolder agent = new ServletHolder(ServletContainer.class);
       agent.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
       agent.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
-              "com.sun.jersey.api.core.PackagesResourceConfig");
+          "com.sun.jersey.api.core.PackagesResourceConfig");
       agent.setInitParameter("com.sun.jersey.config.property.packages",
       agent.setInitParameter("com.sun.jersey.config.property.packages",
-              "org.apache.ambari.server.agent.rest");
+          "org.apache.ambari.server.agent.rest");
       agent.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature",
       agent.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature",
           "true");
           "true");
       agentroot.addServlet(agent, "/agent/v1/*");
       agentroot.addServlet(agent, "/agent/v1/*");
@@ -240,29 +241,46 @@ public class AmbariServer {
 
 
       ServletHolder cert = new ServletHolder(ServletContainer.class);
       ServletHolder cert = new ServletHolder(ServletContainer.class);
       cert.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
       cert.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
-              "com.sun.jersey.api.core.PackagesResourceConfig");
+          "com.sun.jersey.api.core.PackagesResourceConfig");
       cert.setInitParameter("com.sun.jersey.config.property.packages",
       cert.setInitParameter("com.sun.jersey.config.property.packages",
-              "org.apache.ambari.server.security.unsecured.rest");
+          "org.apache.ambari.server.security.unsecured.rest");
       agentroot.addServlet(cert, "/*");
       agentroot.addServlet(cert, "/*");
       cert.setInitOrder(4);
       cert.setInitOrder(4);
 
 
       ServletHolder resources = new ServletHolder(ServletContainer.class);
       ServletHolder resources = new ServletHolder(ServletContainer.class);
       resources.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
       resources.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
-              "com.sun.jersey.api.core.PackagesResourceConfig");
+          "com.sun.jersey.api.core.PackagesResourceConfig");
       resources.setInitParameter("com.sun.jersey.config.property.packages",
       resources.setInitParameter("com.sun.jersey.config.property.packages",
-        "org.apache.ambari.server.resources.api.rest");
+          "org.apache.ambari.server.resources.api.rest");
       root.addServlet(resources, "/resources/*");
       root.addServlet(resources, "/resources/*");
       resources.setInitOrder(6);
       resources.setInitOrder(6);
-      
+
       //Set jetty thread pool
       //Set jetty thread pool
       serverForAgent.setThreadPool(new QueuedThreadPool(25));
       serverForAgent.setThreadPool(new QueuedThreadPool(25));
       server.setThreadPool(new QueuedThreadPool(25));
       server.setThreadPool(new QueuedThreadPool(25));
-      
+
       /* Configure the API server to use the NIO connectors */
       /* Configure the API server to use the NIO connectors */
-      SelectChannelConnector apiConnector = new SelectChannelConnector();
-      apiConnector.setPort(CLIENT_API_PORT);
+      SelectChannelConnector apiConnector;
+
+      if (configs.getApiSSLAuthentication()) {
+        SslSelectChannelConnector sapiConnector = new SslSelectChannelConnector();
+        sapiConnector.setPort(CLIENT_SSL_API_PORT);
+        sapiConnector.setKeystore(keystore);
+        sapiConnector.setTruststore(keystore);
+        sapiConnector.setPassword(srvrCrtPass);
+        sapiConnector.setKeyPassword(srvrCrtPass);
+        sapiConnector.setTrustPassword(srvrCrtPass);
+        sapiConnector.setKeystoreType("PKCS12");
+        sapiConnector.setTruststoreType("PKCS12");
+        apiConnector = sapiConnector;
+      } 
+      else  {
+        apiConnector = new SelectChannelConnector();
+        apiConnector.setPort(CLIENT_API_PORT);
+      }
+
       server.addConnector(apiConnector);
       server.addConnector(apiConnector);
-      
+
       server.setStopAtShutdown(true);
       server.setStopAtShutdown(true);
       serverForAgent.setStopAtShutdown(true);
       serverForAgent.setStopAtShutdown(true);
       springAppContext.start();
       springAppContext.start();
@@ -305,16 +323,16 @@ public class AmbariServer {
       manager.start();
       manager.start();
       LOG.info("********* Started ActionManager **********");
       LOG.info("********* Started ActionManager **********");
 
 
-//TODO: Remove this code when APIs are ready for testing.
-//      RequestInjectorForTest testInjector = new RequestInjectorForTest(controller, clusters);
-//      Thread testInjectorThread = new Thread(testInjector);
-//      testInjectorThread.start();
+      //TODO: Remove this code when APIs are ready for testing.
+      //      RequestInjectorForTest testInjector = new RequestInjectorForTest(controller, clusters);
+      //      Thread testInjectorThread = new Thread(testInjector);
+      //      testInjectorThread.start();
 
 
       server.join();
       server.join();
       LOG.info("Joined the Server");
       LOG.info("Joined the Server");
     } catch(BindException bindException) {
     } catch(BindException bindException) {
       LOG.error("Could not bind to server port - instance may already be running. " +
       LOG.error("Could not bind to server port - instance may already be running. " +
-        "Terminating this instance.", bindException);
+          "Terminating this instance.", bindException);
       throw bindException;
       throw bindException;
     }
     }
   }
   }

+ 11 - 21
ambari-server/src/main/java/org/apache/ambari/server/controller/HostRequest.java

@@ -26,13 +26,13 @@ public class HostRequest {
 
 
   private String hostname;
   private String hostname;
   private String publicHostname;
   private String publicHostname;
-  private List<String> clusterNames; // CREATE/UPDATE
+  private String clusterName; // CREATE/UPDATE
   private Map<String, String> hostAttributes; // CREATE/UPDATE
   private Map<String, String> hostAttributes; // CREATE/UPDATE
   private String rackInfo;
   private String rackInfo;
 
 
-  public HostRequest(String hostname, List<String> clusterNames, Map<String, String> hostAttributes) {
+  public HostRequest(String hostname, String clusterName, Map<String, String> hostAttributes) {
     this.hostname = hostname;
     this.hostname = hostname;
-    this.clusterNames = clusterNames;
+    this.clusterName = clusterName;
     this.hostAttributes = hostAttributes;
     this.hostAttributes = hostAttributes;
   }
   }
 
 
@@ -44,12 +44,12 @@ public class HostRequest {
     this.hostname = hostname;
     this.hostname = hostname;
   }
   }
 
 
-  public List<String> getClusterNames() {
-    return clusterNames;
+  public String getClusterName() {
+    return clusterName;
   }
   }
 
 
-  public void setClusterNames(List<String> clusterNames) {
-    this.clusterNames = clusterNames;
+  public void setClusterName(String clusterName) {
+    this.clusterName = clusterName;
   }
   }
 
 
   public Map<String, String> getHostAttributes() {
   public Map<String, String> getHostAttributes() {
@@ -78,19 +78,9 @@ public class HostRequest {
 
 
   public String toString() {
   public String toString() {
     StringBuilder sb = new StringBuilder();
     StringBuilder sb = new StringBuilder();
-    sb.append("{"
-        + ", hostname=" + hostname
-        + ", clusterNames=[");
-    if (clusterNames != null) {
-      for (int i = 0; i < clusterNames.size(); ++i) {
-        if (i != 0) {
-          sb.append(",");
-        }
-        sb.append(clusterNames.get(i));
-      }
-    }
+    sb.append("{ hostname=").append(hostname).append(", clusterName=").append(clusterName);
     if (hostAttributes != null) {
     if (hostAttributes != null) {
-      sb.append("], hostAttributes=[");
+      sb.append(", hostAttributes=[");
       int i = 0;
       int i = 0;
       for (Entry<String, String> attr : hostAttributes.entrySet()) {
       for (Entry<String, String> attr : hostAttributes.entrySet()) {
         if (i != 0) {
         if (i != 0) {
@@ -99,9 +89,9 @@ public class HostRequest {
         ++i;
         ++i;
         sb.append(attr.getKey() + "=" + attr.getValue());
         sb.append(attr.getKey() + "=" + attr.getValue());
       }
       }
+      sb.append(']');
     }
     }
-    sb.append("] }");
+    sb.append(" }");
     return sb.toString();
     return sb.toString();
   }
   }
-
 }
 }

+ 10 - 9
ambari-server/src/main/java/org/apache/ambari/server/controller/HostResponse.java

@@ -33,7 +33,7 @@ public class HostResponse {
 
 
   private String hostname;
   private String hostname;
 
 
-  private Set<String> clusterNames;
+  private String clusterName;
 
 
   /**
   /**
    * Host IP if ipv4 interface available
    * Host IP if ipv4 interface available
@@ -120,7 +120,7 @@ public class HostResponse {
    */
    */
   private String hostState;
   private String hostState;
 
 
-  public HostResponse(String hostname, Set<String> clusterNames,
+  public HostResponse(String hostname, String clusterName,
                       String ipv4, String ipv6, int cpuCount, String osArch, String osType,
                       String ipv4, String ipv6, int cpuCount, String osArch, String osType,
                       String osInfo, long availableMemBytes, long totalMemBytes,
                       String osInfo, long availableMemBytes, long totalMemBytes,
                       List<DiskInfo> disksInfo, long lastHeartbeatTime,
                       List<DiskInfo> disksInfo, long lastHeartbeatTime,
@@ -129,7 +129,7 @@ public class HostResponse {
                       HostHealthStatus healthStatus, String hostState) {
                       HostHealthStatus healthStatus, String hostState) {
     super();
     super();
     this.hostname = hostname;
     this.hostname = hostname;
-    this.clusterNames = clusterNames;
+    this.clusterName = clusterName;
     this.ipv4 = ipv4;
     this.ipv4 = ipv4;
     this.ipv6 = ipv6;
     this.ipv6 = ipv6;
     this.cpuCount = cpuCount;
     this.cpuCount = cpuCount;
@@ -148,8 +148,9 @@ public class HostResponse {
     this.setHostState(hostState);
     this.setHostState(hostState);
   }
   }
 
 
+  //todo: why are we passing in empty strings for host/cluster name instead of null?
   public HostResponse(String hostname) {
   public HostResponse(String hostname) {
-    this(hostname, new HashSet<String>(), "", "",
+    this(hostname, "", "", "",
         0, "", "",
         0, "", "",
         "", 0, 0, new ArrayList<DiskInfo>(),
         "", 0, 0, new ArrayList<DiskInfo>(),
         0, 0, "",
         0, 0, "",
@@ -174,15 +175,15 @@ public class HostResponse {
   /**
   /**
    * @return the clusterNames
    * @return the clusterNames
    */
    */
-  public Set<String> getClusterNames() {
-    return clusterNames;
+  public String getClusterName() {
+    return clusterName;
   }
   }
 
 
   /**
   /**
-   * @param clusterNames the clusterNames to set
+   * @param clusterName the name of the associated cluster
    */
    */
-  public void setClusterNames(Set<String> clusterNames) {
-    this.clusterNames = clusterNames;
+  public void setClusterName(String clusterName) {
+    this.clusterName = clusterName;
   }
   }
 
 
   /**
   /**

+ 5 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaHostProvider.java

@@ -17,6 +17,8 @@
  */
  */
 package org.apache.ambari.server.controller.ganglia;
 package org.apache.ambari.server.controller.ganglia;
 
 
+import org.apache.ambari.server.controller.spi.SystemException;
+
 /**
 /**
  *  Provider of Ganglia host information.
  *  Provider of Ganglia host information.
  */
  */
@@ -28,6 +30,8 @@ public interface GangliaHostProvider {
    * @param clusterName  the cluster name
    * @param clusterName  the cluster name
    *
    *
    * @return the Ganglia server
    * @return the Ganglia server
+   *
+   * @throws SystemException if unable to get the Ganglia server host name
    */
    */
-  public String getGangliaCollectorHostName(String clusterName);
+  public String getGangliaCollectorHostName(String clusterName) throws SystemException;
 }
 }

+ 20 - 7
ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaPropertyProvider.java

@@ -18,7 +18,6 @@
 
 
 package org.apache.ambari.server.controller.ganglia;
 package org.apache.ambari.server.controller.ganglia;
 
 
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.internal.PropertyInfo;
 import org.apache.ambari.server.controller.internal.PropertyInfo;
 import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
@@ -30,6 +29,7 @@ import org.slf4j.LoggerFactory;
 
 
 import java.io.IOException;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.List;
@@ -102,11 +102,10 @@ public abstract class GangliaPropertyProvider implements PropertyProvider {
   // ----- PropertyProvider --------------------------------------------------
   // ----- PropertyProvider --------------------------------------------------
 
 
   @Override
   @Override
-  public Set<Resource> populateResources(Set<Resource> resources,
-                                         Request request,
-                                         Predicate predicate) throws AmbariException{
+  public Set<Resource> populateResources(Set<Resource> resources, Request request, Predicate predicate)
+      throws SystemException {
 
 
-    Set<String> ids = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
+    Set<String> ids = PropertyHelper.getRequestPropertyIds(propertyIds, request, predicate);
     if (ids.isEmpty()) {
     if (ids.isEmpty()) {
       return resources;
       return resources;
     }
     }
@@ -130,6 +129,16 @@ public abstract class GangliaPropertyProvider implements PropertyProvider {
     return propertyIds;
     return propertyIds;
   }
   }
 
 
+  @Override
+  public Set<String> checkPropertyIds(Set<String> propertyIds) {
+    if (!this.propertyIds.containsAll(propertyIds)) {
+      Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
+      unsupportedPropertyIds.removeAll(this.propertyIds);
+      return unsupportedPropertyIds;
+    }
+    return Collections.emptySet();
+  }
+
 
 
   // ----- GangliaPropertyProvider -------------------------------------------
   // ----- GangliaPropertyProvider -------------------------------------------
 
 
@@ -256,12 +265,14 @@ public abstract class GangliaPropertyProvider implements PropertyProvider {
    * @param temporalInfo  the temporal information
    * @param temporalInfo  the temporal information
    *
    *
    * @return the spec
    * @return the spec
+   *
+   * @throws SystemException if unable to get the Ganglia Collector host name
    */
    */
   private String getSpec(String clusterName,
   private String getSpec(String clusterName,
                          Set<String> clusterSet,
                          Set<String> clusterSet,
                          Set<String> hostSet,
                          Set<String> hostSet,
                          Set<String> metricSet,
                          Set<String> metricSet,
-                         TemporalInfo temporalInfo) {
+                         TemporalInfo temporalInfo) throws SystemException {
 
 
     String clusters = getSetString(clusterSet, -1);
     String clusters = getSetString(clusterSet, -1);
     String hosts    = getSetString(hostSet, -1);
     String hosts    = getSetString(hostSet, -1);
@@ -397,8 +408,10 @@ public abstract class GangliaPropertyProvider implements PropertyProvider {
      * Populate the associated resources by making the rrd request.
      * Populate the associated resources by making the rrd request.
      *
      *
      * @return a collection of populated resources
      * @return a collection of populated resources
+     *
+     * @throws SystemException if unable to populate the resources
      */
      */
-    public Collection<Resource> populateResources() {
+    public Collection<Resource> populateResources() throws SystemException {
 
 
       String spec = getSpec(clusterName, clusterSet, hostSet, metrics.keySet(), temporalInfo);
       String spec = getSpec(clusterName, clusterSet, hostSet, metrics.keySet(), temporalInfo);
       Collection<Resource> populatedResources = new HashSet<Resource>();
       Collection<Resource> populatedResources = new HashSet<Resource>();

+ 24 - 12
ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/GangliaReportPropertyProvider.java

@@ -18,7 +18,6 @@
 
 
 package org.apache.ambari.server.controller.ganglia;
 package org.apache.ambari.server.controller.ganglia;
 
 
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.internal.PropertyInfo;
 import org.apache.ambari.server.controller.internal.PropertyInfo;
 import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
@@ -29,6 +28,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 
 
 import java.io.IOException;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.List;
@@ -82,7 +82,9 @@ public class GangliaReportPropertyProvider implements PropertyProvider {
   // ----- PropertyProvider --------------------------------------------------
   // ----- PropertyProvider --------------------------------------------------
 
 
   @Override
   @Override
-  public Set<Resource> populateResources(Set<Resource> resources, Request request, Predicate predicate) throws AmbariException{
+  public Set<Resource> populateResources(Set<Resource> resources, Request request, Predicate predicate)
+      throws SystemException {
+
     Set<Resource> keepers = new HashSet<Resource>();
     Set<Resource> keepers = new HashSet<Resource>();
     for (Resource resource : resources) {
     for (Resource resource : resources) {
       if (populateResource(resource, request, predicate)) {
       if (populateResource(resource, request, predicate)) {
@@ -97,6 +99,16 @@ public class GangliaReportPropertyProvider implements PropertyProvider {
     return propertyIds;
     return propertyIds;
   }
   }
 
 
+  @Override
+  public Set<String> checkPropertyIds(Set<String> propertyIds) {
+    if (!this.propertyIds.containsAll(propertyIds)) {
+      Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
+      unsupportedPropertyIds.removeAll(this.propertyIds);
+      return unsupportedPropertyIds;
+    }
+    return Collections.emptySet();
+  }
+
 
 
   // ----- helper methods ----------------------------------------------------
   // ----- helper methods ----------------------------------------------------
 
 
@@ -109,11 +121,12 @@ public class GangliaReportPropertyProvider implements PropertyProvider {
    *
    *
    * @return true if the resource was successfully populated with the requested properties
    * @return true if the resource was successfully populated with the requested properties
    *
    *
-   * @throws AmbariException thrown if the resource cannot be populated
+   * @throws SystemException if unable to populate the resource
    */
    */
-  private boolean populateResource(Resource resource, Request request, Predicate predicate) throws AmbariException{
+  private boolean populateResource(Resource resource, Request request, Predicate predicate)
+      throws SystemException {
 
 
-    if (getPropertyIds().isEmpty()) {
+    if (propertyIds.isEmpty()) {
       return true;
       return true;
     }
     }
     String clusterName = (String) resource.getPropertyValue(clusterNamePropertyId);
     String clusterName = (String) resource.getPropertyValue(clusterNamePropertyId);
@@ -127,16 +140,13 @@ public class GangliaReportPropertyProvider implements PropertyProvider {
     }
     }
 
 
     setProperties(resource, clusterName, request,
     setProperties(resource, clusterName, request,
-        PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate));
+        PropertyHelper.getRequestPropertyIds(propertyIds, request, predicate));
 
 
     return true;
     return true;
   }
   }
 
 
-  private boolean setProperties(Resource resource,
-                                String clusterName,
-                                Request request,
-                                Set<String> ids) {
-
+  private boolean setProperties(Resource resource, String clusterName, Request request, Set<String> ids)
+      throws SystemException {
 
 
     Map<String, Map<String, String>> propertyIdMaps = getPropertyIdMaps(request, ids);
     Map<String, Map<String, String>> propertyIdMaps = getPropertyIdMaps(request, ids);
 
 
@@ -222,8 +232,10 @@ public class GangliaReportPropertyProvider implements PropertyProvider {
    * @param report          the report
    * @param report          the report
    *
    *
    * @return the spec
    * @return the spec
+   *
+   * @throws SystemException if unable to ge the Ganglia Collector host name
    */
    */
-  protected String getSpec(String clusterName, String report) {
+  protected String getSpec(String clusterName, String report) throws SystemException {
 
 
     StringBuilder sb = new StringBuilder();
     StringBuilder sb = new StringBuilder();
 
 

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/ganglia/MetricsMapping.java

@@ -1,5 +1,23 @@
 package org.apache.ambari.server.controller.ganglia;
 package org.apache.ambari.server.controller.ganglia;
 
 
+/**
+ * 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.
+ */
+
 /**
 /**
  *
  *
  */
  */

+ 38 - 16
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActionResourceProvider.java

@@ -20,17 +20,13 @@ package org.apache.ambari.server.controller.internal;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.ActionRequest;
 import org.apache.ambari.server.controller.ActionRequest;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.RequestStatus;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.Set;
@@ -61,32 +57,60 @@ class ActionResourceProvider extends ResourceProviderImpl {
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus createResources(Request request) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.Action, request);
-    Set<ActionRequest> requests = new HashSet<ActionRequest>();
+  public RequestStatus createResources(Request request)
+      throws SystemException,
+             UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
+    final Set<ActionRequest> requests = new HashSet<ActionRequest>();
     for (Map<String, Object> propertyMap : request.getProperties()) {
     for (Map<String, Object> propertyMap : request.getProperties()) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
-    return getRequestStatus(getManagementController().createActions(requests));
+    return getRequestStatus(createResources(new Command<RequestStatusResponse>() {
+      @Override
+      public RequestStatusResponse invoke() throws AmbariException {
+        return getManagementController().createActions(requests);
+      }
+    }));
   }
   }
 
 
   @Override
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
   public Set<Resource> getResources(Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     throw new UnsupportedOperationException("Not currently supported.");
     throw new UnsupportedOperationException("Not currently supported.");
   }
   }
 
 
   @Override
   @Override
   public RequestStatus updateResources(Request request, Predicate predicate)
   public RequestStatus updateResources(Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     throw new UnsupportedOperationException("Not currently supported.");
     throw new UnsupportedOperationException("Not currently supported.");
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus deleteResources(Predicate predicate) throws AmbariException, UnsupportedPropertyException {
+  public RequestStatus deleteResources(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     throw new UnsupportedOperationException("Not currently supported.");
     throw new UnsupportedOperationException("Not currently supported.");
   }
   }
 
 
+  @Override
+  public Set<String> checkPropertyIds(Set<String> propertyIds) {
+    propertyIds = super.checkPropertyIds(propertyIds);
+
+    if (propertyIds.isEmpty()) {
+      return propertyIds;
+    }
+    Set<String> unsupportedProperties = new HashSet<String>();
+
+    for (String propertyId : propertyIds) {
+      String propertyCategory = PropertyHelper.getPropertyCategory(propertyId);
+      if (propertyCategory == null || !propertyCategory.equals("parameters")) {
+        unsupportedProperties.add(propertyId);
+      }
+    }
+    return unsupportedProperties;
+  }
+
   @Override
   @Override
   protected Set<String> getPKPropertyIds() {
   protected Set<String> getPKPropertyIds() {
     return pkPropertyIds;
     return pkPropertyIds;
@@ -94,9 +118,7 @@ class ActionResourceProvider extends ResourceProviderImpl {
 
 
   private ActionRequest getRequest(Map<String, Object> properties) {
   private ActionRequest getRequest(Map<String, Object> properties) {
     Map<String, String> params = new HashMap<String, String>();
     Map<String, String> params = new HashMap<String, String>();
-    Iterator<Entry<String, Object>> it1 = properties.entrySet().iterator();
-    while (it1.hasNext()) {
-      Entry<String, Object> entry = it1.next();
+    for (Entry<String, Object> entry : properties.entrySet()) {
       String propertyid = entry.getKey();
       String propertyid = entry.getKey();
       if (PropertyHelper.getPropertyCategory(propertyid).equals("parameters")
       if (PropertyHelper.getPropertyCategory(propertyid).equals("parameters")
           && null != entry.getValue()) {
           && null != entry.getValue()) {

+ 126 - 83
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java

@@ -19,16 +19,7 @@
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
 import org.apache.ambari.server.controller.spi.ProviderModule;
 import org.apache.ambari.server.controller.spi.ProviderModule;
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.controller.spi.ClusterController;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.PropertyProvider;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.RequestStatus;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.ResourceProvider;
-import org.apache.ambari.server.controller.spi.Schema;
-import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
@@ -85,9 +76,12 @@ public class ClusterControllerImpl implements ClusterController {
   // ----- ClusterController -------------------------------------------------
   // ----- ClusterController -------------------------------------------------
 
 
   @Override
   @Override
-  public Iterable<Resource> getResources(Resource.Type type,
-                                         Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException{
+  public Iterable<Resource> getResources(Resource.Type type, Request request, Predicate predicate)
+      throws UnsupportedPropertyException,
+             SystemException,
+             NoSuchParentResourceException,
+             NoSuchResourceException {
+
     ResourceProvider provider = ensureResourceProvider(type);
     ResourceProvider provider = ensureResourceProvider(type);
     ensurePropertyProviders(type);
     ensurePropertyProviders(type);
     Set<Resource> resources;
     Set<Resource> resources;
@@ -99,6 +93,8 @@ public class ClusterControllerImpl implements ClusterController {
           + provider.getClass().getName()
           + provider.getClass().getName()
           + " for request type " + type.toString());
           + " for request type " + type.toString());
 
 
+      checkProperties(type, request, predicate);
+
       resources = provider.getResources(request, predicate);
       resources = provider.getResources(request, predicate);
       resources = populateResources(type, resources, request, predicate);
       resources = populateResources(type, resources, request, predicate);
     }
     }
@@ -121,44 +117,59 @@ public class ClusterControllerImpl implements ClusterController {
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus createResources(Resource.Type type,
-                                       Request request)
-      throws AmbariException, UnsupportedPropertyException {
+  public RequestStatus createResources(Resource.Type type, Request request)
+      throws UnsupportedPropertyException,
+             SystemException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
     ResourceProvider provider = ensureResourceProvider(type);
     ResourceProvider provider = ensureResourceProvider(type);
     if (provider != null) {
     if (provider != null) {
+
+      checkProperties(type, request, null);
+
       return provider.createResources(request);
       return provider.createResources(request);
     }
     }
     return null;
     return null;
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus updateResources(Resource.Type type,
-                                       Request request,
-                                       Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
+  public RequestStatus updateResources(Resource.Type type, Request request, Predicate predicate)
+      throws UnsupportedPropertyException,
+             SystemException,
+             NoSuchResourceException,
+             NoSuchParentResourceException {
+
     ResourceProvider provider = ensureResourceProvider(type);
     ResourceProvider provider = ensureResourceProvider(type);
     if (provider != null) {
     if (provider != null) {
-      predicate = checkPredicate(type, request, predicate);
-      if (predicate == null) {
-        return null;
+
+      if (!checkProperties(type, request, predicate)) {
+        predicate = resolvePredicate(type, predicate);
+        if (predicate == null) {
+          return null;
+        }
       }
       }
-      return provider.updateResources(request, predicate);
+        return provider.updateResources(request, predicate);
     }
     }
     return null;
     return null;
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus deleteResources(Resource.Type type,
-                                       Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
+  public RequestStatus deleteResources(Resource.Type type, Predicate predicate)
+      throws UnsupportedPropertyException,
+             SystemException,
+             NoSuchResourceException,
+             NoSuchParentResourceException {
 
 
     ResourceProvider provider = ensureResourceProvider(type);
     ResourceProvider provider = ensureResourceProvider(type);
     if (provider != null) {
     if (provider != null) {
-      predicate = checkPredicate(type, null, predicate);
-      if (predicate == null) {
-        return null;
+      if (!checkProperties(type, null, predicate)) {
+        predicate = resolvePredicate(type, predicate);
+        if (predicate == null) {
+          return null;
+        }
       }
       }
-      return provider.deleteResources(predicate);
+        return provider.deleteResources(predicate);
     }
     }
     return null;
     return null;
   }
   }
@@ -167,28 +178,25 @@ public class ClusterControllerImpl implements ClusterController {
   // ----- helper methods ----------------------------------------------------
   // ----- helper methods ----------------------------------------------------
 
 
   /**
   /**
-   * Check to see if any of the property ids specified in the given request and
-   * predicate are handled by an associated property provider.  if so, then use
-   * the given predicate to obtain a new predicate that can be completely
-   * processed by an update or delete operation on a resource provider for
-   * the given resource type.  This means that the new predicate should only
-   * reference the key property ids for this type.
+   * Check to make sure that all the property ids specified in the given request and
+   * predicate are supported by the resource provider or property providers for the
+   * given type.
    *
    *
    * @param type       the resource type
    * @param type       the resource type
    * @param request    the request
    * @param request    the request
    * @param predicate  the predicate
    * @param predicate  the predicate
    *
    *
-   * @return the given predicate if a new one is not required; a new predicate if required
-   *
-   * @throws AmbariException thrown if the new predicate can not be obtained
+   * @return true if all of the properties specified in the request and predicate are supported by
+   *         the resource provider for the given type; false if any of the properties specified in
+   *         the request and predicate are not supported by the resource provider but are supported
+   *         by a property provider for the given type.
    *
    *
    * @throws UnsupportedPropertyException thrown if any of the properties specified in the request
    * @throws UnsupportedPropertyException thrown if any of the properties specified in the request
    *                                      and predicate are not supported by either the resource
    *                                      and predicate are not supported by either the resource
    *                                      provider or a property provider for the given type
    *                                      provider or a property provider for the given type
    */
    */
-  private Predicate checkPredicate(Resource.Type type, Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
-
+  private boolean checkProperties(Resource.Type type, Request request, Predicate predicate)
+      throws UnsupportedPropertyException {
     Set<String> requestPropertyIds = request == null ? new HashSet<String>() :
     Set<String> requestPropertyIds = request == null ? new HashSet<String>() :
         PropertyHelper.getAssociatedPropertyIds(request);
         PropertyHelper.getAssociatedPropertyIds(request);
 
 
@@ -198,50 +206,84 @@ public class ClusterControllerImpl implements ClusterController {
 
 
     if (requestPropertyIds.size() > 0) {
     if (requestPropertyIds.size() > 0) {
       ResourceProvider provider = ensureResourceProvider(type);
       ResourceProvider provider = ensureResourceProvider(type);
-      requestPropertyIds.removeAll(provider.getPropertyIds());
-
-      // if any of the properties are handled by a property provider then
-      // get a new predicate based on the primary key fields
-      List<PropertyProvider> propertyProviders = ensurePropertyProviders(type);
-      for (PropertyProvider propertyProvider : propertyProviders) {
-        if (requestPropertyIds.removeAll(propertyProvider.getPropertyIds())) {
-          Set<String>  keyPropertyIds = new HashSet<String>(provider.getKeyPropertyIds().values());
-          Request          readRequest    = PropertyHelper.getReadRequest(keyPropertyIds);
-
-          Iterable<Resource> resources = getResources(type, readRequest, predicate);
-
-          PredicateBuilder pb = new PredicateBuilder();
-          PredicateBuilder.PredicateBuilderWithPredicate pbWithPredicate = null;
-
-          for (Resource resource : resources) {
-            if (pbWithPredicate != null) {
-              pb = pbWithPredicate.or();
-            }
-
-            pb              = pb.begin();
-            pbWithPredicate = null;
-
-            for (String keyPropertyId : keyPropertyIds) {
-              if (pbWithPredicate != null) {
-                pb = pbWithPredicate.and();
-              }
-              pbWithPredicate =
-                  pb.property(keyPropertyId).equals((Comparable) resource.getPropertyValue(keyPropertyId));
-            }
-            if (pbWithPredicate != null) {
-              pbWithPredicate = pbWithPredicate.end();
-            }
+      requestPropertyIds = provider.checkPropertyIds(requestPropertyIds);
+
+      if (requestPropertyIds.size() > 0) {
+        List<PropertyProvider> propertyProviders = ensurePropertyProviders(type);
+        for (PropertyProvider propertyProvider : propertyProviders) {
+          requestPropertyIds = propertyProvider.checkPropertyIds(requestPropertyIds);
+          if (requestPropertyIds.size() == 0) {
+            return false;
           }
           }
-          return pbWithPredicate == null ? null : pbWithPredicate.toPredicate();
         }
         }
+        throw new UnsupportedPropertyException(type, requestPropertyIds);
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Check to see if any of the property ids specified in the given request and
+   * predicate are handled by an associated property provider.  if so, then use
+   * the given predicate to obtain a new predicate that can be completely
+   * processed by an update or delete operation on a resource provider for
+   * the given resource type.  This means that the new predicate should only
+   * reference the key property ids for this type.
+   *
+   * @param type       the resource type
+   * @param predicate  the predicate
+   *
+   * @return the given predicate if a new one is not required; a new predicate if required
+   *
+   * @throws UnsupportedPropertyException thrown if any of the properties specified in the request
+   *                                      and predicate are not supported by either the resource
+   *                                      provider or a property provider for the given type
+   *
+   * @throws SystemException thrown for internal exceptions
+   * @throws NoSuchResourceException if the resource that is requested doesn't exist
+   * @throws NoSuchParentResourceException if a parent resource of the requested resource doesn't exist
+   */
+  private Predicate resolvePredicate(Resource.Type type, Predicate predicate)
+    throws UnsupportedPropertyException,
+        SystemException,
+        NoSuchResourceException,
+        NoSuchParentResourceException{
+
+    ResourceProvider provider = ensureResourceProvider(type);
+
+    Set<String>  keyPropertyIds = new HashSet<String>(provider.getKeyPropertyIds().values());
+    Request      readRequest    = PropertyHelper.getReadRequest(keyPropertyIds);
+
+    Iterable<Resource> resources = getResources(type, readRequest, predicate);
+
+    PredicateBuilder pb = new PredicateBuilder();
+    PredicateBuilder.PredicateBuilderWithPredicate pbWithPredicate = null;
+
+    for (Resource resource : resources) {
+      if (pbWithPredicate != null) {
+        pb = pbWithPredicate.or();
+      }
+
+      pb              = pb.begin();
+      pbWithPredicate = null;
+
+      for (String keyPropertyId : keyPropertyIds) {
+        if (pbWithPredicate != null) {
+          pb = pbWithPredicate.and();
+        }
+        pbWithPredicate =
+            pb.property(keyPropertyId).equals((Comparable) resource.getPropertyValue(keyPropertyId));
+      }
+      if (pbWithPredicate != null) {
+        pbWithPredicate = pbWithPredicate.end();
       }
       }
     }
     }
-    return predicate;
+    return pbWithPredicate == null ? null : pbWithPredicate.toPredicate();
   }
   }
 
 
   /**
   /**
    * Populate the given resources from the associated property providers.  This
    * Populate the given resources from the associated property providers.  This
-   * method may filter the resources based on the predicated and return a subset
+   * method may filter the resources based on the predicate and return a subset
    * of the given resources.
    * of the given resources.
    *
    *
    * @param type       the resource type
    * @param type       the resource type
@@ -251,12 +293,12 @@ public class ClusterControllerImpl implements ClusterController {
    *
    *
    * @return the set of resources that were successfully populated
    * @return the set of resources that were successfully populated
    *
    *
-   * @throws AmbariException thrown if the resources can not be populated
+   * @throws SystemException if unable to populate the resources
    */
    */
   private Set<Resource> populateResources(Resource.Type type,
   private Set<Resource> populateResources(Resource.Type type,
                                           Set<Resource> resources,
                                           Set<Resource> resources,
                                           Request request,
                                           Request request,
-                                          Predicate predicate) throws AmbariException{
+                                          Predicate predicate) throws SystemException {
     Set<Resource> keepers = resources;
     Set<Resource> keepers = resources;
 
 
     for (PropertyProvider propertyProvider : propertyProviders.get(type)) {
     for (PropertyProvider propertyProvider : propertyProviders.get(type)) {
@@ -283,9 +325,10 @@ public class ClusterControllerImpl implements ClusterController {
       return true;
       return true;
     }
     }
     requestPropertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
     requestPropertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
-    requestPropertyIds.retainAll(provider.getPropertyIds());
 
 
-    return !requestPropertyIds.isEmpty();
+    int size = requestPropertyIds.size();
+
+    return size > provider.checkPropertyIds(requestPropertyIds).size();
   }
   }
 
 
   /**
   /**

+ 54 - 20
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java

@@ -21,11 +21,17 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.ClusterRequest;
 import org.apache.ambari.server.controller.ClusterRequest;
 import org.apache.ambari.server.controller.ClusterResponse;
 import org.apache.ambari.server.controller.ClusterResponse;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
@@ -45,7 +51,6 @@ class ClusterResourceProvider extends ResourceProviderImpl{
   protected static final String CLUSTER_ID_PROPERTY_ID      = PropertyHelper.getPropertyId("Clusters", "cluster_id");
   protected static final String CLUSTER_ID_PROPERTY_ID      = PropertyHelper.getPropertyId("Clusters", "cluster_id");
   protected static final String CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Clusters", "cluster_name");
   protected static final String CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Clusters", "cluster_name");
   protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
   protected static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
-  protected static final String CLUSTER_HOSTS_PROPERTY_ID   = PropertyHelper.getPropertyId("Clusters", "hosts");
 
 
 
 
   private static Set<String> pkPropertyIds =
   private static Set<String> pkPropertyIds =
@@ -70,11 +75,20 @@ class ClusterResourceProvider extends ResourceProviderImpl{
 // ----- ResourceProvider ------------------------------------------------
 // ----- ResourceProvider ------------------------------------------------
 
 
   @Override
   @Override
-  public RequestStatus createResources(Request request) throws AmbariException, UnsupportedPropertyException {
-
-    checkRequestProperties(Resource.Type.Cluster, request);
-    for (Map<String, Object> properties : request.getProperties()) {
-      getManagementController().createCluster(getRequest(properties));
+  public RequestStatus createResources(Request request)
+      throws SystemException,
+             UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
+    for (final Map<String, Object> properties : request.getProperties()) {
+      createResources(new Command<Void>() {
+        @Override
+        public Void invoke() throws AmbariException {
+          getManagementController().createCluster(getRequest(properties));
+          return null;
+        }
+      });
     }
     }
     notifyCreate(Resource.Type.Cluster, request);
     notifyCreate(Resource.Type.Cluster, request);
 
 
@@ -82,12 +96,19 @@ class ClusterResourceProvider extends ResourceProviderImpl{
   }
   }
 
 
   @Override
   @Override
-  public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    ClusterRequest clusterRequest = getRequest(getProperties(predicate));
-    Set<String> requestedIds   = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    final ClusterRequest clusterRequest = getRequest(PredicateHelper.getProperties(predicate));
+    Set<String> requestedIds = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
 
 
     // TODO : handle multiple requests
     // TODO : handle multiple requests
-    Set<ClusterResponse> responses = getManagementController().getClusters(Collections.singleton(clusterRequest));
+    Set<ClusterResponse> responses = getResources(new Command<Set<ClusterResponse>>() {
+      @Override
+      public Set<ClusterResponse> invoke() throws AmbariException {
+        return getManagementController().getClusters(Collections.singleton(clusterRequest));
+      }
+    });
 
 
     Set<Resource> resources = new HashSet<Resource>();
     Set<Resource> resources = new HashSet<Resource>();
     if (LOG.isDebugEnabled()) {
     if (LOG.isDebugEnabled()) {
@@ -113,25 +134,38 @@ class ClusterResourceProvider extends ResourceProviderImpl{
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus updateResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.Cluster, request);
+  public RequestStatus updateResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
     for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
     for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
-      ClusterRequest clusterRequest = getRequest(propertyMap);
-      getManagementController().updateCluster(clusterRequest);
+      final ClusterRequest clusterRequest = getRequest(propertyMap);
+
+      modifyResources(new Command<RequestStatusResponse>() {
+        @Override
+        public RequestStatusResponse invoke() throws AmbariException {
+          return getManagementController().updateCluster(clusterRequest);
+        }
+      });
     }
     }
     notifyUpdate(Resource.Type.Cluster, request, predicate);
     notifyUpdate(Resource.Type.Cluster, request, predicate);
-
     return getRequestStatus(null);
     return getRequestStatus(null);
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus deleteResources(Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    for (Map<String, Object> propertyMap : getPropertyMaps(null, predicate)) {
-      ClusterRequest clusterRequest = getRequest(propertyMap);
-      getManagementController().deleteCluster(clusterRequest);
+  public RequestStatus deleteResources(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+      final ClusterRequest clusterRequest = getRequest(propertyMap);
+      modifyResources(new Command<Void>() {
+        @Override
+        public Void invoke() throws AmbariException {
+          getManagementController().deleteCluster(clusterRequest);
+          return null;
+        }
+      });
     }
     }
     notifyDelete(Resource.Type.Cluster, predicate);
     notifyDelete(Resource.Type.Cluster, predicate);
-
     return getRequestStatus(null);
     return getRequestStatus(null);
   }
   }
 
 

+ 57 - 26
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ComponentResourceProvider.java

@@ -22,11 +22,7 @@ import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ServiceComponentRequest;
 import org.apache.ambari.server.controller.ServiceComponentRequest;
 import org.apache.ambari.server.controller.ServiceComponentResponse;
 import org.apache.ambari.server.controller.ServiceComponentResponse;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.RequestStatus;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
@@ -75,29 +71,49 @@ class ComponentResourceProvider extends ResourceProviderImpl{
   // ----- ResourceProvider ------------------------------------------------
   // ----- ResourceProvider ------------------------------------------------
 
 
   @Override
   @Override
-  public RequestStatus createResources(Request request) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.Component, request);
-    Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
+  public RequestStatus createResources(Request request)
+      throws SystemException,
+             UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
+    final Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
     for (Map<String, Object> propertyMap : request.getProperties()) {
     for (Map<String, Object> propertyMap : request.getProperties()) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
-    getManagementController().createComponents(requests);
+
+    createResources(new Command<Void>() {
+      @Override
+      public Void invoke() throws AmbariException {
+        getManagementController().createComponents(requests);
+        return null;
+      }
+    });
+
     notifyCreate(Resource.Type.Component, request);
     notifyCreate(Resource.Type.Component, request);
 
 
     return getRequestStatus(null);
     return getRequestStatus(null);
   }
   }
 
 
   @Override
   @Override
-  public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
 
 
-    for (Map<String, Object> propertyMap : getPropertyMaps(null, predicate)) {
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
 
 
-    Set<String>               requestedIds = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
-    Set<ServiceComponentResponse> responses     = getManagementController().getComponents(requests);
-    Set<Resource>                 resources    = new HashSet<Resource>();
+    Set<ServiceComponentResponse> responses = getResources(new Command<Set<ServiceComponentResponse>>() {
+      @Override
+      public Set<ServiceComponentResponse> invoke() throws AmbariException {
+        return getManagementController().getComponents(requests);
+      }
+    });
+
+    Set<String>   requestedIds = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
+    Set<Resource> resources    = new HashSet<Resource>();
 
 
     for (ServiceComponentResponse response : responses) {
     for (ServiceComponentResponse response : responses) {
       Resource resource = new ResourceImpl(Resource.Type.Component);
       Resource resource = new ResourceImpl(Resource.Type.Component);
@@ -114,13 +130,13 @@ class ComponentResourceProvider extends ResourceProviderImpl{
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus updateResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.Component, request);
-    Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
+  public RequestStatus updateResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
     for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
     for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
       ServiceComponentRequest compRequest = getRequest(propertyMap);
       ServiceComponentRequest compRequest = getRequest(propertyMap);
-
-      Map<String, String> configMap = new HashMap<String,String>();
+      Map<String, String>     configMap   = new HashMap<String,String>();
 
 
       for (Map.Entry<String,Object> entry : propertyMap.entrySet()) {
       for (Map.Entry<String,Object> entry : propertyMap.entrySet()) {
         if (PropertyHelper.getPropertyCategory(entry.getKey()).equals("config")) {
         if (PropertyHelper.getPropertyCategory(entry.getKey()).equals("config")) {
@@ -133,21 +149,36 @@ class ComponentResourceProvider extends ResourceProviderImpl{
 
 
       requests.add(compRequest);
       requests.add(compRequest);
     }
     }
-    RequestStatusResponse response = getManagementController().updateComponents(requests);
+
+    RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
+      @Override
+      public RequestStatusResponse invoke() throws AmbariException {
+        return getManagementController().updateComponents(requests);
+      }
+    });
+
     notifyUpdate(Resource.Type.Component, request, predicate);
     notifyUpdate(Resource.Type.Component, request, predicate);
 
 
     return getRequestStatus(response);
     return getRequestStatus(response);
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus deleteResources(Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
-    for (Map<String, Object> propertyMap : getPropertyMaps(null, predicate)) {
+  public RequestStatus deleteResources(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    final Set<ServiceComponentRequest> requests = new HashSet<ServiceComponentRequest>();
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
-    RequestStatusResponse response = getManagementController().deleteComponents(requests);
-    notifyDelete(Resource.Type.Component, predicate);
 
 
+    RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
+      @Override
+      public RequestStatusResponse invoke() throws AmbariException {
+        return getManagementController().deleteComponents(requests);
+      }
+    });
+
+    notifyDelete(Resource.Type.Component, predicate);
     return getRequestStatus(response);
     return getRequestStatus(response);
   }
   }
 
 

+ 97 - 22
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java

@@ -1,22 +1,44 @@
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.ConfigurationRequest;
 import org.apache.ambari.server.controller.ConfigurationRequest;
 import org.apache.ambari.server.controller.ConfigurationResponse;
 import org.apache.ambari.server.controller.ConfigurationResponse;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.RequestStatus;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PredicateHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
@@ -29,9 +51,10 @@ class ConfigurationResourceProvider extends ResourceProviderImpl {
   // ----- Property ID constants ---------------------------------------------
   // ----- Property ID constants ---------------------------------------------
 
 
   // Configurations (values are part of query strings and body post, so they don't have defined categories)
   // Configurations (values are part of query strings and body post, so they don't have defined categories)
-  protected static final String CONFIGURATION_CLUSTER_NAME_PROPERTY_ID    = PropertyHelper.getPropertyId("Config", "cluster_name");
-  protected static final String CONFIGURATION_CONFIG_TYPE_PROPERTY_ID     = PropertyHelper.getPropertyId(null, "type");
-  protected static final String CONFIGURATION_CONFIG_TAG_PROPERTY_ID      = PropertyHelper.getPropertyId(null, "tag");
+  protected static final String CONFIGURATION_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Config", "cluster_name");
+  // TODO : should these be Config/type and Config/tag to be consistent?
+  protected static final String CONFIGURATION_CONFIG_TYPE_PROPERTY_ID  = PropertyHelper.getPropertyId(null, "type");
+  protected static final String CONFIGURATION_CONFIG_TAG_PROPERTY_ID   = PropertyHelper.getPropertyId(null, "tag");
 
 
   private static final String CONFIG_HOST_NAME = PropertyHelper.getPropertyId("Config", "host_name");
   private static final String CONFIG_HOST_NAME = PropertyHelper.getPropertyId("Config", "host_name");
   private static final String CONFIG_COMPONENT_NAME = PropertyHelper.getPropertyId("Config", "component_name");
   private static final String CONFIG_COMPONENT_NAME = PropertyHelper.getPropertyId("Config", "component_name");
@@ -51,44 +74,62 @@ class ConfigurationResourceProvider extends ResourceProviderImpl {
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus createResources(Request request) throws AmbariException, UnsupportedPropertyException {
+  public RequestStatus createResources(Request request)
+      throws SystemException,
+             UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
     for (Map<String, Object> map : request.getProperties()) {
     for (Map<String, Object> map : request.getProperties()) {
 
 
       String cluster = (String) map.get(CONFIGURATION_CLUSTER_NAME_PROPERTY_ID);
       String cluster = (String) map.get(CONFIGURATION_CLUSTER_NAME_PROPERTY_ID);
+      // TODO : why not CONFIGURATION_CONFIG_TYPE_PROPERTY_ID?
       String type = (String) map.get(PropertyHelper.getPropertyId("", "type"));
       String type = (String) map.get(PropertyHelper.getPropertyId("", "type"));
+      // TODO : why not CONFIGURATION_CONFIG_TAG_PROPERTY_ID?
       String tag = (String) map.get(PropertyHelper.getPropertyId("", "tag"));
       String tag = (String) map.get(PropertyHelper.getPropertyId("", "tag"));
+
       Map<String, String> configMap = new HashMap<String, String>();
       Map<String, String> configMap = new HashMap<String, String>();
 
 
-      Iterator<Map.Entry<String, Object>> it1 = map.entrySet().iterator();
-      while (it1.hasNext()) {
-        Map.Entry<String, Object> entry = it1.next();
+      for (Entry<String, Object> entry : map.entrySet()) {
         if (PropertyHelper.getPropertyCategory(entry.getKey()).equals("properties") && null != entry.getValue()) {
         if (PropertyHelper.getPropertyCategory(entry.getKey()).equals("properties") && null != entry.getValue()) {
           configMap.put(PropertyHelper.getPropertyName(entry.getKey()), entry.getValue().toString());
           configMap.put(PropertyHelper.getPropertyName(entry.getKey()), entry.getValue().toString());
         }
         }
       }
       }
 
 
-      ConfigurationRequest configRequest = new ConfigurationRequest(cluster, type, tag, configMap);
+      final ConfigurationRequest configRequest = new ConfigurationRequest(cluster, type, tag, configMap);
+
+      createResources(new Command<Void>() {
+        @Override
+        public Void invoke() throws AmbariException {
+          getManagementController().createConfiguration(configRequest);
+          return null;
+        }
+      });
 
 
-      getManagementController().createConfiguration(configRequest);
     }
     }
     return getRequestStatus(null);
     return getRequestStatus(null);
   }
   }
 
 
   @Override
   @Override
   public Set<Resource> getResources(Request request, Predicate predicate)
   public Set<Resource> getResources(Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
-    Map<String, Object> map = getProperties(predicate);
+    throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    Map<String, Object> map = PredicateHelper.getProperties(predicate);
     
     
     if (map.containsKey(CONFIG_HOST_NAME) && map.containsKey(CONFIG_COMPONENT_NAME)) {
     if (map.containsKey(CONFIG_HOST_NAME) && map.containsKey(CONFIG_COMPONENT_NAME)) {
-      ServiceComponentHostRequest hostComponentRequest = new ServiceComponentHostRequest(
+      final ServiceComponentHostRequest hostComponentRequest = new ServiceComponentHostRequest(
           (String) map.get(CONFIGURATION_CLUSTER_NAME_PROPERTY_ID),
           (String) map.get(CONFIGURATION_CLUSTER_NAME_PROPERTY_ID),
           null,
           null,
           (String) map.get(CONFIG_COMPONENT_NAME),
           (String) map.get(CONFIG_COMPONENT_NAME),
           (String) map.get(CONFIG_HOST_NAME),
           (String) map.get(CONFIG_HOST_NAME),
           null, null);
           null, null);
       
       
-      Map<String, String> mappints = getManagementController().getHostComponentDesiredConfigMapping(hostComponentRequest);
-      
+      Map<String, String> mappints = getResources(new Command<Map<String, String>>() {
+        @Override
+        public Map<String, String> invoke() throws AmbariException {
+          return getManagementController().getHostComponentDesiredConfigMapping(hostComponentRequest);
+        }
+      });
+
       Set<Resource> resources = new HashSet<Resource>();
       Set<Resource> resources = new HashSet<Resource>();
       
       
       for (Entry<String, String> entry : mappints.entrySet()) {
       for (Entry<String, String> entry : mappints.entrySet()) {
@@ -110,9 +151,14 @@ class ConfigurationResourceProvider extends ResourceProviderImpl {
       
       
     } else {
     } else {
       // TODO : handle multiple requests
       // TODO : handle multiple requests
-      ConfigurationRequest configRequest = getRequest(map);
+      final ConfigurationRequest configRequest = getRequest(map);
       
       
-      Set<ConfigurationResponse> responses = getManagementController().getConfigurations(Collections.singleton(configRequest));
+      Set<ConfigurationResponse> responses = getResources(new Command<Set<ConfigurationResponse>>() {
+        @Override
+        public Set<ConfigurationResponse> invoke() throws AmbariException {
+          return getManagementController().getConfigurations(Collections.singleton(configRequest));
+        }
+      });
 
 
       Set<Resource> resources = new HashSet<Resource>();
       Set<Resource> resources = new HashSet<Resource>();
       for (ConfigurationResponse response : responses) {
       for (ConfigurationResponse response : responses) {
@@ -142,16 +188,42 @@ class ConfigurationResourceProvider extends ResourceProviderImpl {
    */
    */
   @Override
   @Override
   public RequestStatus updateResources(Request request, Predicate predicate)
   public RequestStatus updateResources(Request request, Predicate predicate)
-      throws AmbariException, UnsupportedPropertyException {
-    throw new AmbariException ("Cannot update a Configuration resource.");
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    throw new UnsupportedOperationException("Cannot update a Configuration resource.");
   }
   }
 
 
   /**
   /**
    * Throws an exception, as Configurations cannot be deleted.
    * Throws an exception, as Configurations cannot be deleted.
    */
    */
   @Override
   @Override
-  public RequestStatus deleteResources(Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    throw new AmbariException ("Cannot delete a Configuration resource.");
+  public RequestStatus deleteResources(Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    throw new UnsupportedOperationException("Cannot delete a Configuration resource.");
+  }
+
+  @Override
+  public Set<String> checkPropertyIds(Set<String> propertyIds) {
+    propertyIds = super.checkPropertyIds(propertyIds);
+
+    if (propertyIds.isEmpty()) {
+      return propertyIds;
+    }
+    Set<String> unsupportedProperties = new HashSet<String>();
+
+    for (String propertyId : propertyIds) {
+
+      // TODO : hack to allow for inconsistent property names
+      // for example, the tag property can come here as Config/tag, /tag or tag
+      if (!propertyId.equals("tag") && !propertyId.equals("type") &&
+          !propertyId.equals("/tag") && !propertyId.equals("/type")) {
+
+        String propertyCategory = PropertyHelper.getPropertyCategory(propertyId);
+
+        if (propertyCategory == null || !propertyCategory.equals("properties")) {
+          unsupportedProperties.add(propertyId);
+        }
+      }
+    }
+    return unsupportedProperties;
   }
   }
 
 
   @Override
   @Override
@@ -159,13 +231,16 @@ class ConfigurationResourceProvider extends ResourceProviderImpl {
     return pkPropertyIds;
     return pkPropertyIds;
   }
   }
 
 
-  public static void getConfigPropertyValues(Map<String, Object> propertyMap, Map<String, String> configMap) {
+  public static Map<String, String> getConfigPropertyValues(Map<String, Object> propertyMap) {
+    Map<String, String> configMap = new HashMap<String, String>();
+
     for (Map.Entry<String,Object> entry : propertyMap.entrySet()) {
     for (Map.Entry<String,Object> entry : propertyMap.entrySet()) {
       String propertyId = entry.getKey();
       String propertyId = entry.getKey();
       if (PropertyHelper.getPropertyCategory(propertyId).equals("config")) {
       if (PropertyHelper.getPropertyCategory(propertyId).equals("config")) {
         configMap.put(PropertyHelper.getPropertyName(propertyId), (String) entry.getValue());
         configMap.put(PropertyHelper.getPropertyName(propertyId), (String) entry.getValue());
       }
       }
     }
     }
+    return configMap;
   }
   }
 
 
   private ConfigurationRequest getRequest(Map<String, Object> properties) {
   private ConfigurationRequest getRequest(Map<String, Object> properties) {

+ 17 - 17
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java

@@ -18,7 +18,6 @@
 
 
 package org.apache.ambari.server.controller.internal;
 package org.apache.ambari.server.controller.internal;
 
 
-import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.ganglia.GangliaComponentPropertyProvider;
 import org.apache.ambari.server.controller.ganglia.GangliaComponentPropertyProvider;
 import org.apache.ambari.server.controller.ganglia.GangliaHostComponentPropertyProvider;
 import org.apache.ambari.server.controller.ganglia.GangliaHostComponentPropertyProvider;
@@ -27,16 +26,10 @@ import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider
 import org.apache.ambari.server.controller.ganglia.GangliaHostProvider;
 import org.apache.ambari.server.controller.ganglia.GangliaHostProvider;
 import org.apache.ambari.server.controller.jmx.JMXHostProvider;
 import org.apache.ambari.server.controller.jmx.JMXHostProvider;
 import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
 import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.ProviderModule;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.spi.PropertyProvider;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.ResourceProvider;
 
 
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
@@ -148,13 +141,13 @@ public class DefaultProviderModule implements ProviderModule, ResourceProviderOb
   // ----- JMXHostProvider ---------------------------------------------------
   // ----- JMXHostProvider ---------------------------------------------------
 
 
   @Override
   @Override
-  public String getHostName(String clusterName, String componentName) {
+  public String getHostName(String clusterName, String componentName) throws SystemException {
     checkInit();
     checkInit();
     return clusterHostComponentMap.get(clusterName).get(componentName);
     return clusterHostComponentMap.get(clusterName).get(componentName);
   }
   }
 
 
   @Override
   @Override
-  public Map<String, String> getHostMapping(String clusterName) {
+  public Map<String, String> getHostMapping(String clusterName) throws SystemException {
     checkInit();
     checkInit();
     return clusterHostMap.get(clusterName);
     return clusterHostMap.get(clusterName);
   }
   }
@@ -163,7 +156,7 @@ public class DefaultProviderModule implements ProviderModule, ResourceProviderOb
   // ----- GangliaHostProvider -----------------------------------------------
   // ----- GangliaHostProvider -----------------------------------------------
 
 
   @Override
   @Override
-  public String getGangliaCollectorHostName(String clusterName) {
+  public String getGangliaCollectorHostName(String clusterName) throws SystemException {
     checkInit();
     checkInit();
     return clusterGangliaCollectorMap.get(clusterName);
     return clusterGangliaCollectorMap.get(clusterName);
   }
   }
@@ -253,7 +246,7 @@ public class DefaultProviderModule implements ProviderModule, ResourceProviderOb
     putPropertyProviders(type, providers);
     putPropertyProviders(type, providers);
   }
   }
 
 
-  private void checkInit() {
+  private void checkInit() throws SystemException{
     if (!initialized) {
     if (!initialized) {
       synchronized (this) {
       synchronized (this) {
         if (!initialized) {
         if (!initialized) {
@@ -272,7 +265,7 @@ public class DefaultProviderModule implements ProviderModule, ResourceProviderOb
     }
     }
   }
   }
 
 
-  private void initProviderMaps() {
+  private void initProviderMaps() throws SystemException{
     ResourceProvider provider = getResourceProvider(Resource.Type.Cluster);
     ResourceProvider provider = getResourceProvider(Resource.Type.Cluster);
     Request          request  = PropertyHelper.getReadRequest(CLUSTER_NAME_PROPERTY_ID);
     Request          request  = PropertyHelper.getReadRequest(CLUSTER_NAME_PROPERTY_ID);
 
 
@@ -337,14 +330,21 @@ public class DefaultProviderModule implements ProviderModule, ResourceProviderOb
           }
           }
         }
         }
       }
       }
-    } catch (AmbariException e) {
+    } catch (UnsupportedPropertyException e) {
       if (LOG.isErrorEnabled()) {
       if (LOG.isErrorEnabled()) {
-        LOG.error("Caught exception while trying to get the host mappings.", e);
+        LOG.error("Caught UnsupportedPropertyException while trying to get the host mappings.", e);
       }
       }
-    } catch (UnsupportedPropertyException e) {
+      throw new SystemException("An exception occurred while initializing the host mappings: " + e, e);
+    } catch (NoSuchResourceException e) {
+      if (LOG.isErrorEnabled()) {
+        LOG.error("Caught NoSuchResourceException exception while trying to get the host mappings.", e);
+      }
+      throw new SystemException("An exception occurred while initializing the host mappings: " + e, e);
+    } catch (NoSuchParentResourceException e) {
       if (LOG.isErrorEnabled()) {
       if (LOG.isErrorEnabled()) {
-        LOG.error("Caught exception while trying to get the host mappings.", e);
+        LOG.error("Caught NoSuchParentResourceException exception while trying to get the host mappings.", e);
       }
       }
+      throw new SystemException("An exception occurred while initializing the host mappings: " + e, e);
     }
     }
   }
   }
 }
 }

+ 90 - 40
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java

@@ -22,23 +22,19 @@ import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.RequestStatusResponse;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostRequest;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
 import org.apache.ambari.server.controller.ServiceComponentHostResponse;
-import org.apache.ambari.server.controller.spi.Predicate;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.RequestStatus;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 
 
 import java.util.Arrays;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
 /**
 /**
  * Resource provider for host component resources.
  * Resource provider for host component resources.
  */
  */
-class HostComponentResourceProvider extends ResourceProviderImpl{
+class HostComponentResourceProvider extends ResourceProviderImpl {
 
 
   // ----- Property ID constants ---------------------------------------------
   // ----- Property ID constants ---------------------------------------------
 
 
@@ -77,29 +73,50 @@ class HostComponentResourceProvider extends ResourceProviderImpl{
   // ----- ResourceProvider ------------------------------------------------
   // ----- ResourceProvider ------------------------------------------------
 
 
   @Override
   @Override
-  public RequestStatus createResources(Request request) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.HostComponent, request);
-    Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+  public RequestStatus createResources(Request request)
+      throws SystemException,
+             UnsupportedPropertyException,
+             ResourceAlreadyExistsException,
+             NoSuchParentResourceException {
+
+    final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
     for (Map<String, Object> propertyMap : request.getProperties()) {
     for (Map<String, Object> propertyMap : request.getProperties()) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
-    getManagementController().createHostComponents(requests);
+
+    createResources(new Command<Void>() {
+      @Override
+      public Void invoke() throws AmbariException {
+        getManagementController().createHostComponents(requests);
+        return null;
+      }
+    });
+
     notifyCreate(Resource.Type.HostComponent, request);
     notifyCreate(Resource.Type.HostComponent, request);
 
 
     return getRequestStatus(null);
     return getRequestStatus(null);
   }
   }
 
 
   @Override
   @Override
-  public Set<Resource> getResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+  public Set<Resource> getResources(Request request, Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
 
 
-    for (Map<String, Object> propertyMap : getPropertyMaps(null, predicate)) {
+    final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
 
 
-    Set<String>                   requestedIds = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
-    Set<ServiceComponentHostResponse> responses     = getManagementController().getHostComponents(requests);
-    Set<Resource>                     resources    = new HashSet<Resource>();
+    Set<Resource> resources    = new HashSet<Resource>();
+    Set<String>   requestedIds = PropertyHelper.getRequestPropertyIds(getPropertyIds(), request, predicate);
+
+    Set<ServiceComponentHostResponse> responses = getResources(new Command<Set<ServiceComponentHostResponse>>() {
+      @Override
+      public Set<ServiceComponentHostResponse> invoke() throws AmbariException {
+        return getManagementController().getHostComponents(requests);
+      }
+    });
+
     for (ServiceComponentHostResponse response : responses) {
     for (ServiceComponentHostResponse response : responses) {
       Resource resource = new ResourceImpl(Resource.Type.HostComponent);
       Resource resource = new ResourceImpl(Resource.Type.HostComponent);
       setResourceProperty(resource, HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
       setResourceProperty(resource, HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, response.getClusterName(), requestedIds);
@@ -118,41 +135,66 @@ class HostComponentResourceProvider extends ResourceProviderImpl{
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus updateResources(Request request, Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    checkRequestProperties(Resource.Type.HostComponent, request);
-    Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
-    for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
-
-      ServiceComponentHostRequest hostCompRequest = getRequest(propertyMap);
-
-      Map<String, String> configMap = new HashMap<String,String>();
-
-      ConfigurationResourceProvider.getConfigPropertyValues(propertyMap, configMap);
-
-      if (0 != configMap.size()) {
-        hostCompRequest.setConfigVersions(configMap);
+  public RequestStatus updateResources(Request request, Predicate predicate)
+        throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+    RequestStatusResponse response = null;
+
+    Iterator<Map<String,Object>> iterator = request.getProperties().iterator();
+    if (iterator.hasNext()) {
+      for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+        requests.add(getRequest(propertyMap));
       }
       }
-
-      requests.add(hostCompRequest);
+      response = modifyResources(new Command<RequestStatusResponse>() {
+        @Override
+        public RequestStatusResponse invoke() throws AmbariException {
+          return getManagementController().updateHostComponents(requests);
+        }
+      });
+
+      notifyUpdate(Resource.Type.HostComponent, request, predicate);
     }
     }
-    RequestStatusResponse response = getManagementController().updateHostComponents(requests);
-    notifyUpdate(Resource.Type.HostComponent, request, predicate);
-
     return getRequestStatus(response);
     return getRequestStatus(response);
   }
   }
 
 
   @Override
   @Override
-  public RequestStatus deleteResources(Predicate predicate) throws AmbariException, UnsupportedPropertyException {
-    Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
-    for (Map<String, Object> propertyMap : getPropertyMaps(null, predicate)) {
+  public RequestStatus deleteResources(Predicate predicate)
+      throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    final Set<ServiceComponentHostRequest> requests = new HashSet<ServiceComponentHostRequest>();
+    for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
       requests.add(getRequest(propertyMap));
       requests.add(getRequest(propertyMap));
     }
     }
-    RequestStatusResponse response = getManagementController().deleteHostComponents(requests);
+    RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
+      @Override
+      public RequestStatusResponse invoke() throws AmbariException {
+        return getManagementController().deleteHostComponents(requests);
+      }
+    });
+
     notifyDelete(Resource.Type.HostComponent, predicate);
     notifyDelete(Resource.Type.HostComponent, predicate);
 
 
     return getRequestStatus(response);
     return getRequestStatus(response);
   }
   }
 
 
+  @Override
+  public Set<String> checkPropertyIds(Set<String> propertyIds) {
+    propertyIds = super.checkPropertyIds(propertyIds);
+
+    if (propertyIds.isEmpty()) {
+      return propertyIds;
+    }
+    Set<String> unsupportedProperties = new HashSet<String>();
+
+    for (String propertyId : propertyIds) {
+      String propertyCategory = PropertyHelper.getPropertyCategory(propertyId);
+      if (propertyCategory == null || !propertyCategory.equals("config")) {
+        unsupportedProperties.add(propertyId);
+      }
+    }
+    return unsupportedProperties;
+  }
+
+
   // ----- utility methods -------------------------------------------------
   // ----- utility methods -------------------------------------------------
 
 
   @Override
   @Override
@@ -168,12 +210,20 @@ class HostComponentResourceProvider extends ResourceProviderImpl{
    * @return the component request object
    * @return the component request object
    */
    */
   private ServiceComponentHostRequest getRequest(Map<String, Object> properties) {
   private ServiceComponentHostRequest getRequest(Map<String, Object> properties) {
-    return new ServiceComponentHostRequest(
+    ServiceComponentHostRequest serviceComponentHostRequest = new ServiceComponentHostRequest(
         (String) properties.get(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
         (String) properties.get(HOST_COMPONENT_HOST_NAME_PROPERTY_ID),
         null,
         null,
         (String) properties.get(HOST_COMPONENT_STATE_PROPERTY_ID));
         (String) properties.get(HOST_COMPONENT_STATE_PROPERTY_ID));
+
+    Map<String, String> configMappings =
+        ConfigurationResourceProvider.getConfigPropertyValues(properties);
+
+    if (configMappings.size() > 0) {
+      serviceComponentHostRequest.setConfigVersions(configMappings);
+    }
+    return serviceComponentHostRequest;
   }
   }
 }
 }

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff