cloudbox-server 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/.yardopts +3 -0
  2. data/README.md +17 -0
  3. data/bin/cb-cluster-allocate +5 -0
  4. data/bin/cb-cluster-create +5 -0
  5. data/bin/cb-cluster-delete +5 -0
  6. data/bin/cb-cluster-desallocate +5 -0
  7. data/bin/cb-cluster-info +5 -0
  8. data/bin/cb-cluster-ls +5 -0
  9. data/bin/cb-node-destroy +5 -0
  10. data/bin/cb-node-detach +6 -0
  11. data/bin/cb-node-info +5 -0
  12. data/bin/cb-node-install +5 -0
  13. data/bin/cb-node-ls +5 -0
  14. data/bin/cb-service-add +5 -0
  15. data/bin/cb-service-component-add +5 -0
  16. data/bin/cb-service-component-delete +5 -0
  17. data/bin/cb-service-component-detach +5 -0
  18. data/bin/cb-service-conf-apply +5 -0
  19. data/bin/cb-service-conf-create +5 -0
  20. data/bin/cb-service-conf-get +5 -0
  21. data/bin/cb-service-conf-ls +5 -0
  22. data/bin/cb-service-follow-request +5 -0
  23. data/bin/cb-service-info +5 -0
  24. data/bin/cb-service-install +5 -0
  25. data/bin/cb-service-ls +5 -0
  26. data/bin/cb-service-start +5 -0
  27. data/bin/cb-service-stop +5 -0
  28. data/lib/command.rb +61 -0
  29. data/lib/command/ambari_add_host.rb +19 -0
  30. data/lib/command/ambari_cluster_command.rb +26 -0
  31. data/lib/command/ambari_cluster_component_command.rb +26 -0
  32. data/lib/command/ambari_cluster_component_host_command.rb +26 -0
  33. data/lib/command/ambari_cluster_create.rb +19 -0
  34. data/lib/command/ambari_cluster_host_command.rb +27 -0
  35. data/lib/command/ambari_cluster_list.rb +20 -0
  36. data/lib/command/ambari_cluster_service_command.rb +26 -0
  37. data/lib/command/ambari_cluster_service_host_command.rb +26 -0
  38. data/lib/command/ambari_command.rb +21 -0
  39. data/lib/command/ambari_create_cluster_configuration.rb +39 -0
  40. data/lib/command/ambari_get_cluster_configuration.rb +29 -0
  41. data/lib/command/ambari_host_list.rb +19 -0
  42. data/lib/command/ambari_install_cluster.rb +19 -0
  43. data/lib/command/ambari_install_component.rb +19 -0
  44. data/lib/command/ambari_install_host.rb +19 -0
  45. data/lib/command/ambari_install_host_component.rb +19 -0
  46. data/lib/command/ambari_install_host_components.rb +19 -0
  47. data/lib/command/ambari_install_service_components.rb +19 -0
  48. data/lib/command/ambari_service_add.rb +27 -0
  49. data/lib/command/ambari_service_component_add.rb +21 -0
  50. data/lib/command/ambari_service_component_delete.rb +21 -0
  51. data/lib/command/ambari_service_component_detach.rb +21 -0
  52. data/lib/command/ambari_service_component_info.rb +29 -0
  53. data/lib/command/ambari_service_conf_apply.rb +31 -0
  54. data/lib/command/ambari_service_conf_ls.rb +30 -0
  55. data/lib/command/ambari_service_delete.rb +21 -0
  56. data/lib/command/ambari_service_info.rb +20 -0
  57. data/lib/command/ambari_service_list.rb +21 -0
  58. data/lib/command/ambari_start_cluster.rb +19 -0
  59. data/lib/command/ambari_start_component.rb +19 -0
  60. data/lib/command/ambari_start_host.rb +19 -0
  61. data/lib/command/ambari_start_host_component.rb +19 -0
  62. data/lib/command/ambari_start_host_components.rb +19 -0
  63. data/lib/command/ambari_start_service_components.rb +19 -0
  64. data/lib/command/ambari_stop_cluster.rb +19 -0
  65. data/lib/command/ambari_stop_component.rb +19 -0
  66. data/lib/command/ambari_stop_host.rb +19 -0
  67. data/lib/command/ambari_stop_host_component.rb +19 -0
  68. data/lib/command/ambari_stop_host_components.rb +19 -0
  69. data/lib/command/ambari_stop_service_components.rb +19 -0
  70. data/lib/command/basic_command.rb +44 -0
  71. data/lib/command/cluster_create.rb +50 -0
  72. data/lib/command/cluster_delete.rb +30 -0
  73. data/lib/command/cluster_info.rb +30 -0
  74. data/lib/command/cluster_ls.rb +30 -0
  75. data/lib/command/crowbar_cluster_allocate.rb +42 -0
  76. data/lib/command/crowbar_command.rb +30 -0
  77. data/lib/command/crowbar_get_barclamps_list.rb +30 -0
  78. data/lib/command/crowbar_node_command.rb +21 -0
  79. data/lib/command/crowbar_node_list.rb +40 -0
  80. data/lib/command/crowbar_vcluster_command.rb +20 -0
  81. data/lib/command/filter.rb +15 -0
  82. data/lib/command/node_destroy.rb +58 -0
  83. data/lib/command/node_detach.rb +44 -0
  84. data/lib/command/node_info.rb +27 -0
  85. data/lib/command/node_install.rb +46 -0
  86. data/lib/command/node_reinstall.rb +44 -0
  87. data/lib/command/state_filter.rb +16 -0
  88. data/lib/common.rb +11 -0
  89. data/lib/common/cb-lib-node-erase-hard-disk.sh +29 -0
  90. data/lib/common/cloudbox_exceptions.rb +631 -0
  91. data/lib/common/cloudbox_logger.rb +81 -0
  92. data/lib/common/cloudbox_logger_mock.rb +43 -0
  93. data/lib/common/color.rb +267 -0
  94. data/lib/common/config_properties.rb +2027 -0
  95. data/lib/common/services_description.rb +192 -0
  96. data/lib/exec.rb +35 -0
  97. data/lib/exec/check_parameter.rb +208 -0
  98. data/lib/exec/cluster_allocate.rb +163 -0
  99. data/lib/exec/cluster_create.rb +99 -0
  100. data/lib/exec/cluster_delete.rb +38 -0
  101. data/lib/exec/cluster_desallocate.rb +37 -0
  102. data/lib/exec/cluster_info.rb +177 -0
  103. data/lib/exec/cluster_ls.rb +150 -0
  104. data/lib/exec/command_option.rb +222 -0
  105. data/lib/exec/executable_command.rb +194 -0
  106. data/lib/exec/node_destroy.rb +101 -0
  107. data/lib/exec/node_detach.rb +98 -0
  108. data/lib/exec/node_info.rb +280 -0
  109. data/lib/exec/node_install.rb +234 -0
  110. data/lib/exec/node_ls.rb +160 -0
  111. data/lib/exec/service_add.rb +224 -0
  112. data/lib/exec/service_component_add.rb +39 -0
  113. data/lib/exec/service_component_delete.rb +37 -0
  114. data/lib/exec/service_component_detach.rb +37 -0
  115. data/lib/exec/service_conf_apply.rb +57 -0
  116. data/lib/exec/service_conf_create.rb +80 -0
  117. data/lib/exec/service_conf_get.rb +165 -0
  118. data/lib/exec/service_conf_ls.rb +103 -0
  119. data/lib/exec/service_follow_request.rb +49 -0
  120. data/lib/exec/service_info.rb +346 -0
  121. data/lib/exec/service_install.rb +87 -0
  122. data/lib/exec/service_ls.rb +124 -0
  123. data/lib/exec/service_start.rb +110 -0
  124. data/lib/exec/service_stop.rb +112 -0
  125. data/lib/receiver.rb +14 -0
  126. data/lib/receiver/ambari_receiver.rb +812 -0
  127. data/lib/receiver/ambari_rest_api_connector.rb +599 -0
  128. data/lib/receiver/basic_receiver.rb +28 -0
  129. data/lib/receiver/connector.rb +28 -0
  130. data/lib/receiver/crowbar_receiver.rb +588 -0
  131. data/lib/receiver/crowbar_rest_api_connector.rb +518 -0
  132. data/lib/receiver/crowbar_shell_api.rb +643 -0
  133. data/lib/receiver/rest_api_connector.rb +275 -0
  134. data/resources/ambari-configurations/HBASE/default_hbase-site +33 -0
  135. data/resources/ambari-configurations/HDFS/default_hdfs-site +49 -0
  136. data/resources/ambari-configurations/HIVE/default_hive-site +33 -0
  137. data/resources/ambari-configurations/MAPREDUCE/default_mapred-site +72 -0
  138. data/resources/ambari-configurations/OOZIE/default_oozie-site +28 -0
  139. data/resources/ambari-configurations/WEBHCAT/default_webhcat-site +18 -0
  140. data/resources/ambari-configurations/ZOOKEEPER/default_zookeeper-site +8 -0
  141. data/resources/ambari-configurations/default_core-site +22 -0
  142. data/resources/ambari-configurations/default_global +141 -0
  143. data/resources/cloudbox-server.conf +10 -0
  144. data/spec/common/services_description.rb +130 -0
  145. data/spec/exec/check_parameter.rb +152 -0
  146. data/spec/exec/command_option_spec.rb +97 -0
  147. metadata +328 -0
@@ -0,0 +1,110 @@
1
+ # This file is part of cloudbox-service project
2
+ # @author tmarmin (INGENSI)
3
+
4
+ require 'exec/executable_command'
5
+ require 'exec/check_parameter'
6
+
7
+ require 'command/ambari_start_component'
8
+ require 'command/ambari_start_host'
9
+ require 'command/ambari_start_host_component'
10
+ require 'command/ambari_start_service_components'
11
+ require 'command/ambari_start_host_component'
12
+ require 'command/ambari_start_cluster'
13
+ require 'command/ambari_service_component_info'
14
+
15
+ require 'common/services_description'
16
+
17
+ include Exec::CheckParameter
18
+ include Common::ServicesDescription
19
+
20
+ module Exec
21
+ # Allows the user to start services.
22
+ # @author tnoguer
23
+ class ServiceStart < ExecutableCommand
24
+
25
+ private
26
+ # Parse and check the parameters of the function.
27
+ # @author tmarmin
28
+ def set_options
29
+ @logger.info("setting options")
30
+ @options.add_option("C", "cluster", "The virtual cluster name.", true, true, method(:check_cluster_name))
31
+ @options.add_option("s", "service", "Limit request to this service.", false, true, method(:check_hadoop_service_name))
32
+ @options.add_option("H", "host", "Limit request to this host.", false, true, method(:check_ambari_host_name))
33
+ @options.add_option("c", "component", "Limit request to this component type.", false, true, method(:check_hadoop_component_name))
34
+ @options.add_option("f", "follow", "Follow completion of the request.", false)
35
+ end
36
+
37
+ private
38
+ # Execution of the command
39
+ def exec
40
+ begin
41
+ Color::print_log("NONE", "Checking dependencies...", @stdout)
42
+ Common::ServicesDescription.get_master_components_deps(@values["service"]).each do |dep_master_component|
43
+ dep_service_name = Common::ServicesDescription.get_service_name_by_comp_name(dep_master_component)
44
+ data = Command::AmbariServiceComponentInfo.new(dep_service_name, @values["cluster"], dep_master_component).exec
45
+
46
+ started = true
47
+ data["host_components"].each do |host_component|
48
+ started = false if host_component["HostRoles"]["state"] != "STARTED"
49
+ end
50
+
51
+ raise MissingDependency.new("Master component #{dep_master_component} has to be started before start #{@values["service"]} service.") unless started
52
+ end
53
+ Color::echo_ok(@stdout)
54
+
55
+ rescue CloudboxError => e
56
+ Color::echo_fail(@stdout)
57
+ raise e
58
+ end
59
+
60
+ msg = "Unknown combination of attributes... (should never happend)"
61
+ cmd = nil
62
+
63
+ if (!@values["host"].nil? && !@values["component"].nil?) || (!@values["service"].nil? && !@values["host"].nil? && !@values["component"].nil?)
64
+ # 3
65
+ # one component on one host
66
+ msg = "Start components #{@values["component"]} on host #{@values["host"]} (@cluster #{@values["cluster"]})."
67
+ cmd = Command::AmbariStartHostComponent.new(@values["cluster"], @values["component"], @values["host"])
68
+
69
+ elsif !@values["component"].nil? || (!@values["service"].nil? && !@values["component"].nil?)
70
+ # 1
71
+ # one component on all hosts
72
+ msg = "Start all components (@cluster #{@values["cluster"]})."
73
+ cmd = Command::AmbariStartComponent.new(@values["cluster"], @values["component"])
74
+
75
+ elsif !@values["service"].nil? && !@values["host"].nil?
76
+ # 5
77
+ # all component on one host for one service
78
+ # @todo it is the same case than number 3
79
+ msg = "Start components #{@values["component"]} of service #{@values["service"]} on host #{@values["host"]} (@cluster #{@values["cluster"]})."
80
+ cmd = Command::AmbariStartHostComponents.new(@values["cluster"], @values["service"], @values["host"])
81
+
82
+ elsif !@values["host"].nil?
83
+ # 2
84
+ # all component on one host
85
+ msg = "Start all components on host #{@values["host"]} (@cluster #{@values["cluster"]})."
86
+ cmd = Command::AmbariStartHost.new(@values["cluster"], @values["host"])
87
+
88
+ elsif !@values["service"].nil?
89
+ # 4
90
+ # all component on all hosts for one service
91
+ msg = "Start all components #{@values["component"]} of service #{@values["service"]} on all hosts (@cluster #{@values["cluster"]})."
92
+ cmd = Command::AmbariStartServiceComponents.new(@values["cluster"], @values["service"])
93
+
94
+ elsif @values["service"].nil? && @values["host"].nil? && @values["component"].nil?
95
+ # 6
96
+ # all component on all host for all service
97
+ msg = "Start all components of all services on all hosts (@cluster #{@values["cluster"]})."
98
+ cmd = Command::AmbariStartCluster.new(@values["cluster"])
99
+
100
+ else
101
+ raise StandardError(msg)
102
+ end
103
+
104
+ Color::print_log("NONE", msg, @stdout)
105
+ cmd.exec()
106
+ Color::echo_ok(@stdout)
107
+ end
108
+
109
+ end
110
+ end
@@ -0,0 +1,112 @@
1
+ # This file is part of cloudbox-service project
2
+ # @author tmarmin (INGENSI)
3
+
4
+ require 'exec/executable_command'
5
+ require 'exec/check_parameter'
6
+
7
+ require 'command/ambari_stop_component'
8
+ require 'command/ambari_stop_host'
9
+ require 'command/ambari_stop_host_component'
10
+ require 'command/ambari_stop_service_components'
11
+ require 'command/ambari_stop_host_component'
12
+ require 'command/ambari_stop_cluster'
13
+ require 'command/ambari_service_component_info'
14
+
15
+ require 'common/services_description'
16
+
17
+ include Exec::CheckParameter
18
+ include Common::ServicesDescription
19
+
20
+ module Exec
21
+ # Allows the user to stop host components.
22
+ # @author tnoguer
23
+ class ServiceStop < ExecutableCommand
24
+
25
+ private
26
+ # Parse and check the parameters of the function.
27
+ # @author tmarmin
28
+ def set_options
29
+ @logger.info("setting options")
30
+ @options.add_option("C", "cluster", "The virtual cluster name.", true, true, method(:check_cluster_name))
31
+ @options.add_option("s", "service", "Limit request to this service.", false, true, method(:check_hadoop_service_name))
32
+ @options.add_option("H", "host", "Limit request to this host.", false, true, method(:check_ambari_host_name))
33
+ @options.add_option("c", "component", "Limit request to this component type.", false, true, method(:check_hadoop_component_name))
34
+ @options.add_option("f", "follow", "Follow completion of the request.", false)
35
+ end
36
+
37
+ private
38
+ # Execution of the command
39
+ # @author tnoguer
40
+ def exec
41
+
42
+ begin
43
+ Color::print_log("NONE", "Checking dependencies...", @stdout)
44
+ Common::ServicesDescription.get_master_components_depends_on(@values["service"]).each do |dep_master_component|
45
+ dep_service_name = Common::ServicesDescription.get_service_name_by_comp_name(dep_master_component)
46
+ data = Command::AmbariServiceComponentInfo.new(dep_service_name, @values["cluster"], dep_master_component).exec
47
+
48
+ stopped = true
49
+ data["host_components"].each do |host_component|
50
+ stopped = false if host_component["HostRoles"]["status"] != "STOPPED"
51
+ end
52
+
53
+ raise MissingDependency.new("Master component #{dep_master_component} has to be stopped before stop #{@values["service"]} service.") unless stopped
54
+ end
55
+ Color::echo_ok(@stdout)
56
+
57
+ rescue CloudboxError => e
58
+ Color::echo_fail(@stdout)
59
+ raise e
60
+ end
61
+
62
+ msg = "Unknown combination of attributes... (should never happend)"
63
+ cmd = nil
64
+
65
+ if (!@values["host"].nil? && !@values["component"].nil?) || (!@values["service"].nil? && !@values["host"].nil? && !@values["component"].nil?)
66
+ # 3
67
+ # one component on one host
68
+ msg = "Stop components #{@values["component"]} on host #{@values["host"]} (@cluster #{@values["cluster"]})."
69
+ cmd = Command::AmbariStopHostComponent.new(@values["cluster"], @values["component"], @values["host"])
70
+
71
+ elsif !@values["component"].nil? || (!@values["service"].nil? && !@values["component"].nil?)
72
+ # 1
73
+ # one component on all hosts
74
+ msg = "Stop all components (@cluster #{@values["cluster"]})."
75
+ cmd = Command::AmbariStopComponent.new(@values["cluster"], @values["component"])
76
+
77
+ elsif !@values["service"].nil? && !@values["host"].nil?
78
+ # 5
79
+ # all component on one host for one service
80
+ # @todo it is the same case than number 3
81
+ msg = "Stop components #{@values["component"]} of service #{@values["service"]} on host #{@values["host"]} (@cluster #{@values["cluster"]})."
82
+ cmd = Command::AmbariStopHostComponents.new(@values["cluster"], @values["service"], @values["host"])
83
+
84
+ elsif !@values["host"].nil?
85
+ # 2
86
+ # all component on one host
87
+ msg = "Stop all components on host #{@values["host"]} (@cluster #{@values["cluster"]})."
88
+ cmd = Command::AmbariStopHost.new(@values["cluster"], @values["host"])
89
+
90
+ elsif !@values["service"].nil?
91
+ # 4
92
+ # all component on all hosts for one service
93
+ msg = "Stop all components #{@values["component"]} of service #{@values["service"]} on all hosts (@cluster #{@values["cluster"]})."
94
+ cmd = Command::AmbariStopServiceComponents.new(@values["cluster"], @values["service"])
95
+
96
+ elsif @values["service"].nil? && @values["host"].nil? && @values["component"].nil?
97
+ # 6
98
+ # all component on all host for all service
99
+ msg = "Stop all components of all services on all hosts (@cluster #{@values["cluster"]})."
100
+ cmd = Command::AmbariStopCluster.new(@values["cluster"])
101
+
102
+ else
103
+ raise StandardError(msg)
104
+ end
105
+
106
+ Color::print_log("NONE", msg, @stdout)
107
+ cmd.exec()
108
+ Color::echo_ok(@stdout)
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,14 @@
1
+ # This file is part of cloudbox-service project
2
+ # Author: tmarmin
3
+ # Created: 8/21/13 10:38 AM
4
+
5
+ $: << File.dirname(__FILE__)
6
+
7
+ require 'receiver/basic_receiver'
8
+ require 'receiver/ambari_receiver'
9
+ require 'receiver/ambari_rest_api_connector'
10
+ require 'receiver/connector'
11
+ require 'receiver/crowbar_receiver'
12
+ require 'receiver/crowbar_rest_api_connector'
13
+ require 'receiver/crowbar_shell_api'
14
+ require 'receiver/rest_api_connector'
@@ -0,0 +1,812 @@
1
+ # This file is part of cloudbox-server project
2
+ # @author tnoguer (INGENSI)
3
+
4
+ require 'rubygems'
5
+ require 'json'
6
+ require 'receiver/basic_receiver'
7
+ require 'receiver/ambari_rest_api_connector'
8
+ require 'common/cloudbox_exceptions'
9
+
10
+
11
+ module Receiver
12
+ # Class listing all the available methods to interact with Ambari.
13
+ # @author tnoguer
14
+ # @todo Catch the HTTPError and throw a new one with just the error message.
15
+ # @todo Reformat the returned arrays to remove the http notion.
16
+ # @todo Refactor names and private methods below
17
+ class AmbariReceiver < BasicReceiver
18
+
19
+ public
20
+ @@hadoop_services_description = {
21
+ "HDFS" => {
22
+ "MASTER" => %w{NAMENODE SECONDARY_NAMENODE},
23
+ "SLAVE" => %w{DATANODE}},
24
+ "MAPREDUCE" => {
25
+ "MASTER" => %w{JOBTRACKER},
26
+ "SLAVE" => %w{TASKTRACKER}},
27
+ "HIVE" => {
28
+ "MASTER" => %w{HIVE_SERVER},
29
+ "SLAVE" => []},
30
+ "HBASE" => {
31
+ "MASTER" => %w{HBASE_MASTER},
32
+ "SLAVE" => %w{HBASE_REGIONSERVER}},
33
+ "ZOOKEEPER" => {
34
+ "MASTER" => %w{ZOOKEEPER_SERVER},
35
+ "SLAVE" => []},
36
+ "OOZIE" => {
37
+ "MASTER" => %w{OOZIE_SERVER},
38
+ "SLAVE" => []},
39
+ "NAGIOS" => {
40
+ "MASTER" => %w{NAGIOS_SERVER},
41
+ "SLAVE" => []},
42
+ "GANGLIA" => {
43
+ "MASTER" => %w{GANGLIA_SERVER},
44
+ "SLAVE" => []}
45
+ }
46
+
47
+ protected
48
+ @@available_actions = {'START' => {'required_state' => %w{INSTALLED STARTED START_FAILED},
49
+ 'target_state' => 'STARTED'},
50
+ 'STOP' => {'required_state' => %w{STARTED INSTALLED STOP_FAILED},
51
+ 'target_state' => 'INSTALLED'},
52
+ 'INSTALL' => {'required_state' => %w{INIT MAINTENANCE INSTALLED INSTALL_FAILED},
53
+ 'target_state' => 'INSTALLED'},
54
+ 'DETACH' => {'required_state' => %w{INSTALLED MAINTENANCE},
55
+ 'target_state' => 'MAINTENANCE'},
56
+ 'DELETE' => {'required_state' => %w{MAINTENANCE},
57
+ 'target_state' => nil}}
58
+
59
+ public
60
+ # Get the component list of service_name.
61
+ # It includes master and slave nodes.
62
+ # @todo throw an exception of type UnknownHadoopService
63
+ # @param service_name [String] The hadoop service name.
64
+ # @return [Array<String>] The list of components.
65
+ def self.get_components_by_service_name(service_name)
66
+ return nil if !valid_service?(service_name) # @todo throw exception
67
+
68
+ components = []
69
+
70
+ components.concat(@@hadoop_services_description[service_name]["MASTER"])
71
+ components.concat(@@hadoop_services_description[service_name]["SLAVE"])
72
+
73
+ return components
74
+ end
75
+
76
+ public
77
+ # Get the component list of service_name.
78
+ # It includes master and slave nodes.
79
+ # @todo throw an exception of type UnknownHadoopComponent
80
+ # @param component_name [String] The hadoop component name.
81
+ # @return [String] The related service name.
82
+ def self.get_service_by_component_name(component_name)
83
+ return nil if !valid_component?(component_name) # @todo throw exception
84
+
85
+ @@hadoop_services_description.each do |service_name|
86
+ return service_name if get_components_by_service_name(service_name).include?(component_name)
87
+ end
88
+
89
+ return nil
90
+ end
91
+
92
+ public
93
+ # Check if service_name is a Hadoop service.
94
+ # @param service_name [String] The Hadoop service name.
95
+ # @return true if service_name is a known hadoop service.
96
+ def self.valid_service?(service_name)
97
+ return true if @@hadoop_services_description.has_key?(service_name)
98
+ end
99
+
100
+ public
101
+ # Check if component_name is a Hadoop service.
102
+ # @param component_name [String] The Hadoop component name.
103
+ # @return true if component_name is a known hadoop component.
104
+ def self.valid_component?(component_name)
105
+ @@hadoop_services_description.each_key do |service|
106
+ return true if get_component_by_service_name(service).include?(component_name)
107
+ end
108
+ return false
109
+ end
110
+
111
+ public
112
+ # Check if a component is part of a service
113
+ # @todo throw an exception of type UnknownHadoopService if the service_name doesn't exists.
114
+ # @todo throw and exception of type UnknownHadoopComponent if the component_name doesn't exists.
115
+ # @param service_name [String] The Hadoop service name.
116
+ # @param component_name [String] The Hadoop component name.
117
+ # @return true if component_name is a component of service service_name.
118
+ def self.valid_service_component?(service_name, component_name)
119
+ return nil if !valid_service?(service_name) # @todo throw an exception
120
+ return nil if !valid_component?(component_name) # @todo throw an exception
121
+
122
+ @@hadoop_services_description[service_name].each_value do |component|
123
+ return true if component == component_name
124
+ end
125
+
126
+ return false
127
+ end
128
+
129
+ private
130
+ # The connector to the rest API.
131
+ @rest_connector
132
+
133
+ public
134
+ # Default constructor.
135
+ # @author tnoguer
136
+ def initialize(logger = nil)
137
+ super(logger)
138
+ @rest_connector = Receiver::AmbariRestAPIConnector.new(logger)
139
+ @logger.info("Command::AmbariReceiver initialize the parameters...")
140
+ end
141
+
142
+ public
143
+ # Create a configuration into a cluster.
144
+ # @param cluster_name The name of the cluster.
145
+ # @param configuration_type The type of the configuration to add.
146
+ # @param configuration_tag The tag of the configuration to add.
147
+ # @param configuration_properties The hash of properties for the configuration. (ex: {"Property 1" => "value", "Property 2" => "value"})
148
+ # @return The http response.
149
+ # @raise [ArgumentError] If any argument is nil.
150
+ # @raise [HTTPError] If the request is invalid.
151
+ # @author tnoguer
152
+ def create_configuration(cluster_name, configuration_type, configuration_tag, configuration_properties)
153
+ @rest_connector.create_configuration(cluster_name, configuration_type, configuration_tag, configuration_properties)
154
+ end
155
+
156
+ public
157
+ # Create and apply a configuration into a cluster.
158
+ # @param cluster_name The name of the cluster.
159
+ # @param configuration_type The type of the configuration to add.
160
+ # @param configuration_tag The tag of the configuration to add.
161
+ # @param configuration_properties The hash of properties for the configuration. (ex: {"Property 1" => "value", "Property 2" => "value"})
162
+ # @return The http response.
163
+ # @raise [ArgumentError] If any argument is nil.
164
+ # @raise [HTTPError] If the request is invalid.
165
+ # @author tnoguer
166
+ def create_apply_configuration(cluster_name, configuration_type, configuration_tag, configuration_properties)
167
+ @rest_connector.create_apply_configuration(cluster_name, configuration_type, configuration_tag, configuration_properties)
168
+ end
169
+
170
+ public
171
+ # Apply a configuration into a cluster.
172
+ # @param cluster_name The name of the cluster.
173
+ # @param configuration_type The type of the configuration to add.
174
+ # @param configuration_tag The tag of the configuration to add.
175
+ # @return The http response.
176
+ # @raise [ArgumentError] If any argument is nil.
177
+ # @raise [HTTPError] If the request is invalid.
178
+ # @raise [UnknownEntity] If the configuration does not exist.
179
+ # @author tnoguer
180
+ def apply_configuration(cluster_name, configuration_type, configuration_tag)
181
+
182
+ confs = get_cluster_configurations_list(cluster_name)
183
+ exist = false
184
+ confs.each do |conf|
185
+ if (configuration_type == conf["type"] && configuration_tag == conf["tag"])
186
+ exist = true
187
+ end
188
+ end
189
+ raise Common::UnknownEntity.new("Ambari configuration", "Type: #{configuration_type} Tag: #{configuration_tag}") unless exist
190
+
191
+ response = @rest_connector.apply_configuration(cluster_name, configuration_type, configuration_tag)
192
+ end
193
+
194
+ public
195
+ # Defines a new cluster.
196
+ # @param cluster_name The name of the cluster to be defined.
197
+ # @param cluster_version The version of the cluster to be created.
198
+ # @raise [ArgumentError] If any argument is nil.
199
+ # @raise [Common:HTTPError] If the request is invalid.
200
+ # @author tnoguer
201
+ def define_cluster(cluster_name, cluster_version)
202
+ @rest_connector.define_cluster(cluster_name, cluster_version)
203
+ end
204
+
205
+ public
206
+ # Deletes a new cluster.
207
+ # @param cluster_name The name of the cluster to be deleted.
208
+ # @raise [ArgumentError] If any argument is nil.
209
+ # @raise [Common:HTTPError] If the request is invalid.
210
+ # @author tnoguer
211
+ def delete_cluster(cluster_name)
212
+ @rest_connector.delete_cluster(cluster_name)
213
+ end
214
+
215
+ public
216
+ # Shows the hosts of a cluster.
217
+ # @param cluster_name The name of the cluster.
218
+ # @return The result of the request.
219
+ # @raise [ArgumentError] If any argument is nil.
220
+ # @raise [Common:HTTPError] If the request is invalid.
221
+ # @author tnoguer
222
+ def show_cluster_hosts(cluster_name)
223
+ response = @rest_connector.show_cluster_hosts(cluster_name)
224
+ return JSON.parse(response.body)
225
+ end
226
+
227
+ public
228
+ # Shows the services of a cluster.
229
+ # @param cluster_name The name of the cluster.
230
+ # @return The result of the request.
231
+ # @raise [ArgumentError] If any argument is nil.
232
+ # @raise [Common:HTTPError] If the request is invalid.
233
+ # @author tnoguer
234
+ def show_cluster_services(cluster_name)
235
+ response = @rest_connector.show_cluster_services(cluster_name)
236
+ return JSON.parse(response.body)
237
+ end
238
+
239
+ public
240
+ # Returns the list of configuration of a cluster.
241
+ # @param cluster_name The name of the cluster.
242
+ # @return The list of configuration. (ex: {[{"active"=>true,"type"=>value,"tag"=>value}, ...]})
243
+ # @raise [ArgumentError] If any argument is nil.
244
+ # @raise [HTTPError] If the request is invalid.
245
+ # @author tnoguer
246
+ def get_cluster_configurations_list(cluster_name)
247
+ if cluster_name == nil
248
+ raise(ArgumentError, 'Arguments can\'t be nil!')
249
+ end
250
+
251
+ response = @rest_connector.show_cluster(cluster_name)
252
+ confs = JSON.parse(response.body)
253
+ active_confs = confs["Clusters"]["desired_configs"]
254
+ confs = confs["configurations"].sort { |x, y| x["href"] <=> y["href"] }
255
+ confs.each do |conf|
256
+ conf.delete("href")
257
+ conf.delete("Config")
258
+ if (!conf["type"].nil? && active_confs[conf["type"]]["tag"] == conf["tag"])
259
+ conf["active"] = true
260
+ else
261
+ conf["active"] = false
262
+ end
263
+ end
264
+ return confs
265
+ end
266
+
267
+ public
268
+ # Returns the list of configuration of a cluster.
269
+ # @param cluster_name The name of the cluster.
270
+ # @param type The type of configuration.
271
+ # @param tag The tag ot configuration.
272
+ # @return The hash of properties of the configuration. (ex: {"Property name"=>value,"Property name2"=>value}, ...}.
273
+ # @raise [ArgumentError] If any argument is nil.
274
+ # @raise [HTTPError] If the request is invalid.
275
+ # @raise [UnknownEntity] If the configuration does not exist.
276
+ # @author tnoguer
277
+ def get_cluster_configuration(cluster_name, type, tag)
278
+ if cluster_name == nil || type == nil || tag == nil
279
+ raise(ArgumentError, 'Arguments can\'t be nil!')
280
+ end
281
+
282
+ response = @rest_connector.get_cluster_configuration(cluster_name, type, tag)
283
+ conf = JSON.parse(response.body)
284
+ conf = conf["items"][0]
285
+ if conf.nil?
286
+ raise Common::UnknownEntity.new("Ambari configuration", "Type: #{type} Tag: #{tag}")
287
+ end
288
+ return conf["properties"]
289
+ end
290
+
291
+ public
292
+ # Shows the requests of a cluster.
293
+ # @param cluster_name The name of the cluster.
294
+ # @return The result of the request.
295
+ # @raise [ArgumentError] If any argument is nil.
296
+ # @raise [Common:HTTPError] If the request is invalid.
297
+ # @author tnoguer
298
+ def show_requests(cluster_name)
299
+ response = @rest_connector.show_requests(cluster_name)
300
+ return JSON.parse(response.body)
301
+ end
302
+
303
+ public
304
+ # Shows the requests of a cluster.
305
+ # @param cluster_name The name of the cluster.
306
+ # @param request_id The id of the request.
307
+ # @return The result of the request.
308
+ # @raise [ArgumentError] If any argument is nil.
309
+ # @raise [Common:HTTPError] If the request is invalid.
310
+ # @author tnoguer
311
+ def show_request(cluster_name, request_id)
312
+ response = @rest_connector.show_request(cluster_name, request_id)
313
+ return JSON.parse(response.body)
314
+ end
315
+
316
+ public
317
+ # Shows the information of a cluster.
318
+ # @param cluster_name The name of the cluster.
319
+ # @param show_host True to show the detail of the hosts. False otherwise.
320
+ # @param show_components True to show the detail of the components. False otherwise.
321
+ # @return The result of the request.
322
+ # @raise [ArgumentError] If any argument is nil.
323
+ # @raise [Common:HTTPError] If the request is invalid.
324
+ # @author tnoguer
325
+ def show_cluster(cluster_name, show_host, show_components)
326
+ response = @rest_connector.show_cluster(cluster_name, show_host, show_components)
327
+ return JSON.parse(response.body)
328
+ end
329
+
330
+ public
331
+ # Shows the list of clusters.
332
+ # @return The result of the request.
333
+ # @raise [Common:HTTPError] If the request is invalid.
334
+ # @author tnoguerr
335
+ def list_clusters
336
+ response = @rest_connector.list_clusters()
337
+ return JSON.parse(response.body)
338
+ end
339
+
340
+ public
341
+ # Installs every host components of a cluster.
342
+ # @param cluster_name The name of the cluster.
343
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
344
+ # @raise [ArgumentError] If any argument is nil.
345
+ # @raise [Common::HTTPError] If the request is invalid.
346
+ # @author tnoguer
347
+ def install_cluster(cluster_name)
348
+ return execute_method_on_components(method(:install_host_component), cluster_name)
349
+ end
350
+
351
+ public
352
+ # Starts every host components of a cluster.
353
+ # @param cluster_name The name of the cluster.
354
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
355
+ # @raise [ArgumentError] If any argument is nil.
356
+ # @raise [Common::HTTPError] If the request is invalid.
357
+ # @author tnoguer
358
+ def start_cluster(cluster_name)
359
+ return execute_method_on_components(method(:start_host_component), cluster_name)
360
+ end
361
+
362
+ public
363
+ # Stops every host components of a cluster.
364
+ # @param cluster_name The name of the cluster.
365
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
366
+ # @raise [ArgumentError] If any argument is nil.
367
+ # @raise [Common::HTTPError] If the request is invalid.
368
+ # @author tnoguer
369
+ def stop_cluster(cluster_name)
370
+ return execute_method_on_components(method(:stop_host_component), cluster_name)
371
+ end
372
+
373
+
374
+ public
375
+ # Adds a component to an host.
376
+ # @param cluster_name The name of the cluster.
377
+ # @param host_name The name of the host.
378
+ # @param component_name The name of the component to add.
379
+ # @raise [ArgumentError] If any argument is nil.
380
+ # @raise [Common:AlreadyExistsEntity] If the request is invalid.
381
+ # @author tnoguer
382
+ def add_host_component(cluster_name, host_name, component_name)
383
+ begin
384
+ @rest_connector.add_host_component(cluster_name, host_name, component_name)
385
+ rescue ClientError => e
386
+ raise Common::AlreadyExistsEntity.new("host component", component_name, e.to_s) if e.code == 409
387
+ end
388
+ end
389
+
390
+ public
391
+ # Deletes a component from an host.
392
+ # @param cluster_name The name of the cluster.
393
+ # @param host_name The name of the host.
394
+ # @param component_name The name of the component to delete.
395
+ # @raise [ArgumentError] If any argument is nil.
396
+ # @raise [Common::HTTPError] If the request is invalid.
397
+ # @raise [Common::InvalideActionSequence] If the action can't be performed on the host component.
398
+ # @author tnoguer
399
+ def delete_host_component(cluster_name, host_name, component_name)
400
+ valid_action_host_component('DELETE', cluster_name, host_name, component_name)
401
+ @rest_connector.delete_host_component(cluster_name, host_name, component_name)
402
+ end
403
+
404
+ public
405
+ # Deletes an host.
406
+ # @param cluster_name The name of the cluster.
407
+ # @param host_name The name of the host to delete.
408
+ # @raise [ArgumentError] If any argument is nil.
409
+ # @raise [Common::HTTPError] If the request is invalid.
410
+ # @author tnoguer
411
+ def delete_host(cluster_name, host_name)
412
+ @rest_connector.delete_host(cluster_name, host_name)
413
+ end
414
+
415
+ public
416
+ # Installs a component of an host.
417
+ # @param cluster_name The name of the cluster.
418
+ # @param host_name The name of the host.
419
+ # @param component_name The name of the component to install.
420
+ # @return [Int] The ID of the processing request if there is one, Nil otherwise.
421
+ # @raise [ArgumentError] If any argument is nil.
422
+ # @raise [Common::HTTPError] If the request is invalid.
423
+ # @raise [Common::InvalidActionSequence] If the action can't be performed on the host component.
424
+ # @author tnoguer
425
+ def install_host_component(cluster_name, host_name, component_name)
426
+ valid_action_host_component('INSTALL', cluster_name, host_name, component_name)
427
+ response = @rest_connector.install_host_component(cluster_name, host_name, component_name)
428
+ return get_request_id_from_response(response)
429
+ end
430
+
431
+ public
432
+ # Starts a component of an host.
433
+ # @param cluster_name The name of the cluster.
434
+ # @param host_name The name of the host.
435
+ # @param component_name The name of the component to start.
436
+ # @return [Int] The ID of the processing request if there is one, Nil otherwise.
437
+ # @raise [ArgumentError] If any argument is nil.
438
+ # @raise [Common::HTTPError] If the request is invalid.
439
+ # @raise [Common::InvalideActionSequence] If the action can't be performed on the host component.
440
+ # @author tnoguer
441
+ def start_host_component(cluster_name, host_name, component_name)
442
+ valid_action_host_component('START', cluster_name, host_name, component_name)
443
+ response = @rest_connector.start_host_component(cluster_name, host_name, component_name)
444
+ return get_request_id_from_response(response)
445
+ end
446
+
447
+ public
448
+ # Stops a component of an host.
449
+ # @param cluster_name The name of the cluster.
450
+ # @param host_name The name of the host.
451
+ # @param component_name The name of the component to stop.
452
+ # @return [Int] The ID of the processing request if there is one, Nil otherwise.
453
+ # @raise [ArgumentError] If any argument is nil.
454
+ # @raise [Common::HTTPError] If the request is invalid.
455
+ # @raise [Common::InvalideActionSequence] If the action can't be performed on the host component.
456
+ # @author tnoguer
457
+ def stop_host_component(cluster_name, host_name, component_name)
458
+ valid_action_host_component('STOP', cluster_name, host_name, component_name)
459
+ response = @rest_connector.stop_host_component(cluster_name, host_name, component_name)
460
+ return get_request_id_from_response(response)
461
+ end
462
+
463
+ public
464
+ # Detachs a component of an host.
465
+ # @param cluster_name The name of the cluster.
466
+ # @param host_name The name of the host.
467
+ # @param component_name The name of the component to detach.
468
+ # @return [Int] The ID of the processing request if there is one, Nil otherwise.
469
+ # @raise [ArgumentError] If any argument is nil.
470
+ # @raise [Common::HTTPError] If the request is invalid.
471
+ # @raise [Common::InvalideActionSequence] If the action can't be performed on the host component.
472
+ # @author tnoguer
473
+ def detach_host_component(cluster_name, host_name, component_name)
474
+ valid_action_host_component('DETACH', cluster_name, host_name, component_name)
475
+ response = @rest_connector.detach_host_component(cluster_name, host_name, component_name)
476
+ return get_request_id_from_response(response)
477
+ end
478
+
479
+ public
480
+ # Adds an host.
481
+ # @param cluster_name The name of the cluster.
482
+ # @param host_name The name of the host to add.
483
+ # @raise [ArgumentError] If any argument is nil.
484
+ # @raise [Common::HTTPError] If the request is invalid.
485
+ # @author tnoguer
486
+ def add_host(cluster_name, host_name)
487
+ @rest_connector.add_host(cluster_name, host_name)
488
+ end
489
+
490
+ public
491
+ # Gets the list of hosts.
492
+ # @param cluster_name The name of the cluster.
493
+ # @return [Array] The list of hosts.
494
+ # @raise [Common::HTTPError] If the request is invalid.
495
+ def get_host_list(cluster_name)
496
+ response = @rest_connector.show_cluster(cluster_name)
497
+ data = JSON.parse(response.body)
498
+ hosts = []
499
+ data["hosts"].each do |host|
500
+ hosts << host["Hosts"]["host_name"]
501
+ end
502
+ return hosts
503
+ end
504
+
505
+ public
506
+ # Shows information of an host.
507
+ # @param cluster_name The name of the cluster.
508
+ # @param host_name The name of the host.
509
+ # @return The result of the request
510
+ # @raise [ArgumentError] If any argument is nil.
511
+ # @raise [Common::HTTPError] If the request is invalid.
512
+ # @author tnoguer
513
+ def show_host(cluster_name, host_name)
514
+ response = @rest_connector.show_host(cluster_name, host_name)
515
+ return JSON.parse(response.body)
516
+ end
517
+
518
+ public
519
+ # Shows information of an host component.
520
+ # @param cluster_name The name of the cluster.
521
+ # @param host_name The name of the host.
522
+ # @param component_name The name of component.
523
+ # @return [Hash] The information of the host component.
524
+ # @raise [ArgumentError] If any argument is nil.
525
+ # @raise [Common::HTTPError] If the request is invalid.
526
+ # @author tnoguer
527
+ def show_host_component(cluster_name, host_name, component_name)
528
+ response = @rest_connector.show_host(cluster_name, host_name)
529
+ data = JSON.parse(response.body)
530
+ data["host_components"].each do |component|
531
+ if component["HostRoles"]["component_name"] == component_name
532
+ return component["HostRoles"]
533
+ end
534
+ end
535
+ end
536
+
537
+ public
538
+ # Installs every components of an host.
539
+ # @param cluster_name The name of the cluster.
540
+ # @param host_name The name of the host.
541
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
542
+ # @raise [ArgumentError] If any argument is nil.
543
+ # @raise [Common::HTTPError] If the request is invalid.
544
+ # @author tnoguer
545
+ def install_host(cluster_name, host_name)
546
+ return execute_method_on_components(method(:install_host_component), cluster_name, nil, host_name)
547
+ end
548
+
549
+ public
550
+ # Starts every components of an host.
551
+ # @param cluster_name The name of the cluster.
552
+ # @param host_name The name of the host.
553
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
554
+ # @raise [ArgumentError] If any argument is nil.
555
+ # @raise [Common::HTTPError] If the request is invalid.
556
+ # @author tnoguer
557
+ def start_host(cluster_name, host_name)
558
+ return execute_method_on_components(method(:start_host_component), cluster_name, nil, host_name)
559
+ end
560
+
561
+ public
562
+ # Stops every components of an host.
563
+ # @param cluster_name The name of the cluster.
564
+ # @param host_name The name of the host.
565
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
566
+ # @raise [ArgumentError] If any argument is nil.
567
+ # @raise [Common::HTTPError] If the request is invalid.
568
+ # @author tnoguer
569
+ def stop_host(cluster_name, host_name)
570
+ return execute_method_on_components(method(:stop_host_component), cluster_name, nil, host_name)
571
+ end
572
+
573
+ public
574
+ # Installs every components of a specific service for an host.
575
+ # @param cluster_name The name of the cluster.
576
+ # @param service_name The name of the service.
577
+ # @param host_name The name of the host.
578
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
579
+ # @raise [ArgumentError] If any argument is nil.
580
+ # @raise [Common::HTTPError] If the request is invalid.
581
+ # @author tnoguer
582
+ def install_host_components(cluster_name, service_name, host_name)
583
+ return execute_method_on_components(method(:install_host_component), cluster_name, service_name, host_name)
584
+ end
585
+
586
+ public
587
+ # Starts every components of a specific service for an host.
588
+ # @param cluster_name The name of the cluster.
589
+ # @param service_name The name of the service.
590
+ # @param host_name The name of the host.
591
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
592
+ # @raise [ArgumentError] If any argument is nil.
593
+ # @raise [Common::HTTPError] If the request is invalid.
594
+ # @author tnoguer
595
+ def start_host_components(cluster_name, service_name, host_name)
596
+ return execute_method_on_components(method(:start_host_component), cluster_name, service_name, host_name)
597
+ end
598
+
599
+ public
600
+ # Stops every components of a specific service for an host.
601
+ # @param cluster_name The name of the cluster.
602
+ # @param service_name The name of the service.
603
+ # @param host_name The name of the host.
604
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
605
+ # @raise [ArgumentError] If any argument is nil.
606
+ # @raise [Common::HTTPError] If the request is invalid.
607
+ # @author tnoguer
608
+ def stop_host_components(cluster_name, service_name, host_name)
609
+ return execute_method_on_components(method(:stop_host_component), cluster_name, service_name, host_name)
610
+ end
611
+
612
+ public
613
+ # Adds a component to a service.
614
+ # @param cluster_name The name of the cluster.
615
+ # @param service_name The name of the service.
616
+ # @param component_name The name of the component to add.
617
+ # @raise [ArgumentError] If any argument is nil.
618
+ # @raise [Common::HTTPError] If the request is invalid.
619
+ # @author tnoguer
620
+ def add_service_component(cluster_name, service_name, component_name)
621
+ @rest_connector.add_service_component(cluster_name, service_name, component_name)
622
+ end
623
+
624
+ public
625
+ # Defines a new service.
626
+ # @param cluster_name The name of the cluster.
627
+ # @param service_name The name of the service to define.
628
+ # @raise [ArgumentError] If any argument is nil.
629
+ # @raise [Common::HTTPError] If the request is invalid.
630
+ # @raise [Common::AlreadyExistsEntity] If the service is already defined
631
+ # @author tnoguer
632
+ def define_service(cluster_name, service_name)
633
+ begin
634
+ @rest_connector.define_service(cluster_name, service_name)
635
+ rescue ServerError => e
636
+ raise Common::AlreadyExistsEntity.new("service", service_name, e.to_s) if e.code == 409
637
+ end
638
+ end
639
+
640
+ public
641
+ # Deletes a service.
642
+ # @param cluster_name The name of the cluster.
643
+ # @param service_name The name of the service to delete.
644
+ # @raise [ArgumentError] If any argument is nil.
645
+ # @raise [Common::HTTPError] If the request is invalid.
646
+ # @author tnoguer
647
+ def delete_service(cluster_name, service_name)
648
+ @rest_connector.delete_service(cluster_name, service_name)
649
+ end
650
+
651
+ public
652
+ # Installs a service.
653
+ # @param cluster_name The name of the cluster.
654
+ # @param service_name The name of the service to install.
655
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
656
+ # @raise [ArgumentError] If any argument is nil.
657
+ # @raise [Common::HTTPError] If the request is invalid.
658
+ # @author tnoguer
659
+ def install_service(cluster_name, service_name)
660
+ return execute_method_on_components(method(:install_host_component), cluster_name, service_name)
661
+ end
662
+
663
+ public
664
+ # Starts a service.
665
+ # @param cluster_name The name of the cluster.
666
+ # @param service_name The name of the service to start.
667
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
668
+ # @raise [ArgumentError] If any argument is nil.
669
+ # @raise [Common::HTTPError] If the request is invalid.
670
+ # @author tnoguer
671
+ def start_service(cluster_name, service_name)
672
+ return execute_method_on_components(method(:start_host_component), cluster_name, service_name)
673
+ end
674
+
675
+ public
676
+ # Stops a service.
677
+ # @param cluster_name The name of the cluster.
678
+ # @param service_name The name of the service to stop.
679
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
680
+ # @raise [ArgumentError] If any argument is nil.
681
+ # @raise [Common::HTTPError] If the request is invalid.
682
+ # @author tnoguer
683
+ def stop_service(cluster_name, service_name)
684
+ return execute_method_on_components(method(:stop_host_component), cluster_name, service_name)
685
+ end
686
+
687
+ public
688
+ # Installs a type of components of a service.
689
+ # @param cluster_name The name of the cluster.
690
+ # @param component_name The name of the components to install.
691
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
692
+ # @raise [ArgumentError] If any argument is nil.
693
+ # @raise [Common::HTTPError] If the request is invalid.
694
+ # @author tnoguer
695
+ def install_component(cluster_name, component_name)
696
+ return execute_method_on_components(method(:install_host_component), cluster_name, nil, nil, component_name)
697
+ end
698
+
699
+ public
700
+ # Starts a type of component.
701
+ # @param cluster_name The name of the cluster.
702
+ # @param component_name The name of the components to start.
703
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
704
+ # @raise [ArgumentError] If any argument is nil.
705
+ # @raise [Common::HTTPError] If the request is invalid.
706
+ # @author tnoguer
707
+ def start_component(cluster_name, component_name)
708
+ return execute_method_on_components(method(:start_host_component), cluster_name, nil, nil, component_name)
709
+ end
710
+
711
+ public
712
+ # Stops a type of component.
713
+ # @param cluster_name The name of the cluster.
714
+ # @param component_name The name of the components to stops.
715
+ # @return [Array] The IDs of the processing requests. Empty if there is no requests.
716
+ # @raise [ArgumentError] If any argument is nil.
717
+ # @raise [Common::HTTPError] If the request is invalid.
718
+ # @author tnoguer
719
+ def stop_component(cluster_name, component_name)
720
+ return execute_method_on_components(method(:stop_host_component), cluster_name, nil, nil, component_name)
721
+ end
722
+
723
+ public
724
+ # Shows information of a type of components of a service.
725
+ # @param cluster_name The name of the cluster.
726
+ # @param service_name The name of the service.
727
+ # @param component_name The name of the components.
728
+ # @return The result of the request.
729
+ # @raise [ArgumentError] If any argument is nil.
730
+ # @raise [Common::HTTPError] If the request is invalid.
731
+ # @author tnoguer
732
+ def show_service_components(cluster_name, service_name, component_name)
733
+ response = @rest_connector.show_service_components(cluster_name, service_name, component_name)
734
+ return JSON.parse(response.body)
735
+ end
736
+
737
+ public
738
+ # Shows the list of service of a cluster.
739
+ # @param cluster_name The name of the cluster.
740
+ # @param service_name The name of the service.
741
+ # @return The result of the request.
742
+ # @raise [ArgumentError] If any argument is nil.
743
+ # @raise [Common::HTTPError] If the request is invalid.
744
+ # @author tnoguer
745
+ def show_service(cluster_name, service_name)
746
+ response = @rest_connector.show_service(cluster_name, service_name)
747
+ return JSON.parse(response.body)
748
+ end
749
+
750
+ private
751
+ # Checks if the action is valid on the host component.
752
+ # @param action The action to perform.
753
+ # @param cluster_name The name of the cluster.
754
+ # @param host_name The name of the host.
755
+ # @param component_name The name of the component
756
+ # @raise [Common::InvalidActionSequence] If the action can't be performed on the host component.
757
+ # @author tnoguer
758
+ def valid_action_host_component(action, cluster_name, host_name, component_name)
759
+ response = show_host_component(cluster_name, host_name, component_name)
760
+ current_state = response["state"]
761
+ unless @@available_actions[action]['required_state'].include?(current_state)
762
+ raise Common::InvalidActionSequence.new(action, current_state, @@available_actions, "#{component_name}/#{host_name}", "host component")
763
+ end
764
+ end
765
+
766
+ private
767
+ # Execute a method passed in parameter for every host component of a cluster
768
+ # @param method The method to be executed. Must be either install_host_component, start_host_component or stop_host_component
769
+ # @param cluster_name The name of the cluster.
770
+ # @param service_name The name of the service, used to filter to this service.. Can be nil.
771
+ # @param host_name The name of the host, used to filter to this host. Can be nil.
772
+ # @param component_type The type of component, used to filter to this component. Can be nil
773
+ # @return [Array] The returns of the calls of the method.
774
+ # @author tnoguer
775
+ def execute_method_on_components(method, cluster_name, service_name = nil, host_name = nil, component_type = nil)
776
+ request_ids = []
777
+ data = show_cluster(cluster_name, true, true)
778
+ data['services'].each do |service|
779
+ if service_name == nil || service_name == service['ServiceInfo']['service_name']
780
+ service['components'].each do |component|
781
+ if component_type == nil || component_type == component['ServiceComponentInfo']['component_name']
782
+ component['host_components'].each do |host_component|
783
+ if host_name == nil || host_name == host_component['HostRoles']['host_name']
784
+ begin
785
+ request_ids << method.call(cluster_name, host_component['HostRoles']['host_name'], component['ServiceComponentInfo']['component_name'])
786
+ rescue Common::InvalidActionSequence
787
+ # @todo Do a feedback to the interface that the install of the component was ignored.
788
+ end
789
+ end
790
+ end
791
+ end
792
+ end
793
+ end
794
+ end
795
+ return request_ids
796
+ end
797
+
798
+ private
799
+ # Get the id of the ambari request from the http response when the response code is 202.
800
+ # @param response [HTTPReseponse] The http response.
801
+ # @return The id of the request in case there is one, nil otherwise.
802
+ # @author tnoguer
803
+ def get_request_id_from_response(response)
804
+ request_id = nil
805
+ if response.code == '202'
806
+ request_id = JSON.parse(response.body)['Requests']['id']
807
+ end
808
+ return request_id
809
+ end
810
+
811
+ end
812
+ end