note description: "Aranea node to build a software and return build results." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class A_NODE_CONFIG inherit A_NODE redefine listen_queues, register_message_handlers, switches end A_CONFIG_CONSTANTS ARGUMENTS create make feature -- Status is_simulate: BOOLEAN -- Should actions only be simulated and not executed? once Result := has_option (simulate_switch) end feature -- Access name: STRING = "Aranea Config" version: STRING = "$Revision$" feature {NONE} -- Callbacks handle_write_file (a_msg: A_MESSAGE) -- Write file as specified in a_msg. require a_msg_set: a_msg /= Void local l_msg: A_CONFIG_FILE_WRITE_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check file_write_message: l_msg /= Void end write_file (l_msg.name.value, l_msg.content.value) create l_status.make (create {A_BOOLEAN_VALUE}.make (True), create {A_STRING_VALUE}.make ("")) send_message_reply (l_status, a_msg) end handle_write_file_list (a_msg: A_MESSAGE) -- Write files as specified in a_msg. require a_msg_set: a_msg /= Void local l_msg: A_CONFIG_FILE_WRITE_LIST_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_file_list: DS_ARRAYED_LIST [A_CONFIG_CONFIG_FILE_MESSAGE] do l_msg ?= a_msg check file_write_message: l_msg /= Void end -- files are specified as contents mapped to their filename l_file_list := l_msg.files.sequence from l_file_list.start until l_file_list.after loop write_file (l_file_list.item_for_iteration.name.value, l_file_list.item_for_iteration.content.value) -- Increment l_file_list.forth end create l_status.make (create {A_BOOLEAN_VALUE}.make (True), create {A_STRING_VALUE}.make ("")) send_message_reply (l_status, a_msg) end handle_launch_command (a_msg: A_MESSAGE) -- Launch command as described in a_msg. require a_msg_set: a_msg /= Void local l_msg: A_CONFIG_COMMAND_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE do l_msg ?= a_msg check config_command_message: l_msg /= Void end launch_command (l_msg.command.value) create l_status.make (create {A_BOOLEAN_VALUE}.make (True), Void) send_message_reply (l_status, a_msg) end handle_launch_command_list (a_msg: A_MESSAGE) -- Launch commands as described in a_msg. require a_msg_set: a_msg /= Void local l_msg: A_CONFIG_COMMAND_LIST_MESSAGE l_status: A_GENERAL_STATUS_MESSAGE l_command_list: DS_ARRAYED_LIST[A_STRING_VALUE] do l_msg ?= a_msg check config_command_message: l_msg /= Void end l_command_list := l_msg.commands.sequence from l_command_list.start until l_command_list.after loop launch_command (l_command_list.item_for_iteration.value) -- Increment l_command_list.forth end create l_status.make (create {A_BOOLEAN_VALUE}.make (True), Void) send_message_reply (l_status, a_msg) end feature {NONE} -- Argument handling switches: detachable ARRAYED_LIST [attached ARGUMENT_SWITCH] -- Command line switches. local l_assertion_flag: BOOLEAN once -- disable assertion-checking for precursor-assertion-check l_assertion_flag := {ISE_RUNTIME}.check_assert (False) Result := Precursor Result.extend (create {ARGUMENT_SWITCH}.make (simulate_switch, "Only simulate actions?", True, False)) -- restore previous value of assertion-checking l_assertion_flag := {ISE_RUNTIME}.check_assert (l_assertion_flag) end simulate_switch: STRING = "simulate" feature {NONE} -- Configuration queue_names: LIST [STRING] -- Name of the queues to listen for messages. local l_conf: STRING once l_conf := config_parser.get_default ("config_queue", default_config_queue) Result := l_conf.split(',') end feature {NONE} -- Implementation launch_command (a_command: STRING) -- Execute a_command. local l_prc_factory: PROCESS_FACTORY l_prc_launcher: PROCESS l_output: STRING l_error_output: STRING do create l_prc_factory node_logger.debugging ("Exec: " + a_command) if is_simulate then io.put_string ("Exec: ") io.put_string (a_command) io.new_line else create l_output.make (0) create l_error_output.make (0) l_prc_launcher := l_prc_factory.process_launcher_with_command_line (a_command, Void) l_prc_launcher.redirect_output_to_agent (agent l_output.append ({STRING}?)) l_prc_launcher.redirect_error_to_agent (agent l_error_output.append ({STRING}?)) l_prc_launcher.launch if l_prc_launcher.launched then l_prc_launcher.wait_for_exit if not l_output.is_empty then node_logger.info (l_output) end if not l_error_output.is_empty then node_logger.warn (l_error_output) end end end end write_file (a_file_name: STRING; a_content: STRING) -- Write a_content into a_file_name. local l_file: PLAIN_TEXT_FILE do node_logger.debugging ("Write: " + a_file_name) if is_simulate then io.put_string ("Write: ") io.put_string (a_file_name) io.new_line else create l_file.make (a_file_name) if (l_file.exists and then l_file.is_writable) or l_file.is_creatable then l_file.open_write l_file.put_string (a_content) l_file.close end end end listen_queues: DS_LIST [STRING] -- Queues to listen on. once Result := Precursor from queue_names.start until queue_names.after loop Result.put_last (aranea_prefix + queue_names.item_for_iteration.as_upper) queue_names.forth end end register_message_handlers -- Register message handlers. do Precursor register_message_handler (config_namespace, config_file_write_type, agent handle_write_file) register_message_handler (config_namespace, config_file_write_list_type, agent handle_write_file_list) register_message_handler (config_namespace, config_command_type, agent handle_launch_command) register_message_handler (config_namespace, config_command_list_type, agent handle_launch_command_list) end create_msg_factory : A_MESSAGE_FACTORY -- create a new message factory do create Result.make end end