note description: "Origo node for storage access. This node also allows access to any data (also authentication)." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class NODE_STORAGE inherit A_NODE_CLIENT redefine switches, listen_queues, register_message_handlers, aranea_shutdown end O_NODE ARGUMENTS A_CONFIG_CONSTANTS O_USER_CONSTANTS O_PROJECT_CONSTANTS O_WORKITEM_CONSTANTS O_COMMIT_CONSTANTS O_WIKI_CONSTANTS O_COMMENT_CONSTANTS O_BLOG_CONSTANTS O_ISSUE_CONSTANTS O_RELEASE_CONSTANTS O_COMMUNITY_CONSTANTS O_STATISTICS_CONSTANTS O_SYSTEM_CONSTANTS rename system_namespace as origo_system_namespace end EXCEPTIONS O_ERRORS create make feature -- Access Peer_description: STRING = "Storage node to store origo data." -- Node's peer description name: STRING = "Origo Storage" version: STRING = "$Revision$" host: STRING -- Database host. once if has_option (host_switch) then Result := option_of_name (host_switch).value else Result := config_parser.get_default ("storage_host", "localhost") end end source: STRING -- Database source host. once if has_option (source_switch) then Result := option_of_name (source_switch).value else Result := config_parser.get_default ("storage_db", "origo") end end user: STRING -- Database user. once if has_option (user_switch) then Result := option_of_name (user_switch).value else Result := config_parser.get ("storage_user") end end password: STRING -- Database password. once if has_option (password_switch) then Result := option_of_name (password_switch).value else Result := config_parser.get ("storage_password") end 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_VALUE_SWITCH}.make (host_switch, "Database hostname.", True, False, "HOSTNAME", "Hostname of the database server.", False)) Result.extend (create {ARGUMENT_VALUE_SWITCH}.make (source_switch, "Database source.", True, False, "SOURCE", "Data source.", False)) Result.extend (create {ARGUMENT_VALUE_SWITCH}.make (user_switch, "Database user.", True, False, "USER", "User.", False)) Result.extend (create {ARGUMENT_VALUE_SWITCH}.make (password_switch, "Database password.", True, False, "PASS", "Password.", False)) -- restore previous value of assertion-checking l_assertion_flag := {ISE_RUNTIME}.check_assert (l_assertion_flag) end host_switch: STRING = "host" source_switch: STRING = "source" user_switch: STRING = "user" password_switch: STRING = "password" feature {NONE} -- Implementation cleanup_timer: TIMER -- A timer that does some cleanup (e.g. remove old sessions). listen_queues: DS_LIST [STRING] -- Listen queues. once Result := Precursor Result.put_last (origo_storage_queue) end register_message_handlers -- Register message handlers. local l_db_handler: DATABASE_HANDLER l_policy_cache: POLICY_CACHE l_user: USER_INTERFACE l_project: PROJECT_INTERFACE l_workitem: WORKITEM_INTERFACE l_commit: COMMIT_INTERFACE l_wiki: WIKI_INTERFACE l_comment: COMMENT_INTERFACE l_blog: BLOG_INTERFACE l_release: RELEASE_INTERFACE l_issue: ISSUE_INTERFACE l_community: COMMUNITY_INTERFACE l_statistics: STATISTICS_INTERFACE l_system: SYSTEM_INTERFACE l_interval: INTEGER l_interval_string: STRING do Precursor -- create DB handler create l_db_handler.make (host, source, user, password) -- setup global shared policy cache create l_policy_cache.make (l_db_handler) create l_user.make (Current, l_db_handler, l_policy_cache) -- parse interval for origo maintenance timer l_interval_string := config_parser.get ("storage_cleanup_interval") if l_interval_string = Void then l_interval := 600000 -- fallback 10 minutes else l_interval := l_interval_string.to_integer end -- create a cleanup timer that adds the cleanup action to the job_queue create cleanup_timer.make (agent (a_handler: PROCEDURE [ANY, TUPLE []]) do main_jobs.force (agent a_handler.call ([])) end (agent l_user.cleanup), l_interval) cleanup_timer.start register_main_loop_message_handler (user_namespace, user_create_type, agent message_handler_error_wrapper(agent l_user.user_create, ?)) register_main_loop_message_handler (user_namespace, user_login_type, agent message_handler_error_wrapper(agent l_user.user_login, ?)) register_main_loop_message_handler (user_namespace, user_login_authenticated_type, agent message_handler_error_wrapper(agent l_user.user_login_authenticated, ?)) register_main_loop_message_handler (user_namespace, user_login_key_type, agent message_handler_error_wrapper(agent l_user.user_login_key, ?)) register_main_loop_message_handler (user_namespace, user_authorized_for_project_type, agent message_handler_error_wrapper(agent l_user.user_authorized_for_project, ?)) register_main_loop_message_handler (user_namespace, user_authorized_for_community_type, agent message_handler_error_wrapper (agent l_user.user_authorized_for_community, ?)) register_main_loop_message_handler (user_namespace, user_change_email_type, agent message_handler_error_wrapper(agent l_user.user_change_email, ?)) register_main_loop_message_handler (user_namespace, user_change_account_enabled_type, agent message_handler_error_wrapper(agent l_user.user_change_account_enabled, ?)) register_main_loop_message_handler (user_namespace, user_change_password_type, agent message_handler_error_wrapper(agent l_user.user_change_password, ?)) register_main_loop_message_handler (user_namespace, user_reset_password_type, agent message_handler_error_wrapper (agent l_user.user_reset_password, ?)) register_main_loop_message_handler (user_namespace, user_my_name_type, agent message_handler_error_wrapper(agent l_user.user_my_name, ?)) register_main_loop_message_handler (user_namespace, user_my_password_type, agent message_handler_error_wrapper(agent l_user.user_my_password, ?)) register_main_loop_message_handler (user_namespace, user_my_email_type, agent message_handler_error_wrapper(agent l_user.user_my_email, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_email_type, agent message_handler_error_wrapper(agent l_user.user_retrieve_email, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_password_type, agent message_handler_error_wrapper(agent l_user.user_retrieve_password, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_user_from_email_type, agent message_handler_error_wrapper(agent l_user.user_retrieve_user_from_email, ?)) register_main_loop_message_handler (user_namespace, user_profile_visible_type, agent message_handler_error_wrapper(agent l_user.user_profile_visible, ?)) register_main_loop_message_handler (user_namespace, user_change_profile_visible_type, agent message_handler_error_wrapper(agent l_user.user_change_profile_visible, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_information_type, agent message_handler_error_wrapper(agent l_user.user_retrieve_information, ?)) register_main_loop_message_handler (user_namespace, user_set_information_type, agent message_handler_error_wrapper(agent l_user.user_set_information, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_valid_setting_names_type, agent message_handler_error_wrapper(agent l_user.user_valid_setting_names, ?)) register_main_loop_message_handler (user_namespace, user_set_icon_type, agent message_handler_error_wrapper(agent l_user.user_set_icon, ?)) register_main_loop_message_handler (user_namespace, user_reset_icon_type, agent message_handler_error_wrapper(agent l_user.user_reset_icon, ?)) register_main_loop_message_handler (user_namespace, user_key_type, agent message_handler_error_wrapper(agent l_user.key, ?)) register_main_loop_message_handler (user_namespace, user_key_generate_type, agent message_handler_error_wrapper(agent l_user.key_generate, ?)) register_main_loop_message_handler (user_namespace, user_add_bookmark_type, agent message_handler_error_wrapper(agent l_user.add_bookmark, ?)) register_main_loop_message_handler (user_namespace, user_remove_bookmark_type, agent message_handler_error_wrapper(agent l_user.remove_bookmark, ?)) register_main_loop_message_handler (user_namespace, user_list_bookmark_type, agent message_handler_error_wrapper(agent l_user.list_bookmark, ?)) register_main_loop_message_handler (user_namespace, user_set_workitem_subscription_type, agent message_handler_error_wrapper(agent l_user.user_set_workitem_subscription, ?)) register_main_loop_message_handler (user_namespace, user_list_workitem_subscription_type, agent message_handler_error_wrapper(agent l_user.user_list_workitem_subscription, ?)) register_main_loop_message_handler (user_namespace, user_reported_issues_count_type, agent message_handler_error_wrapper(agent l_user.user_reported_issues_count, ?)) register_main_loop_message_handler (user_namespace, user_list_reported_issues_type, agent message_handler_error_wrapper(agent l_user.user_list_reported_issues, ?)) register_main_loop_message_handler (user_namespace, user_request_friendship_type, agent message_handler_error_wrapper(agent l_user.user_request_friendship, ?)) register_main_loop_message_handler (user_namespace, user_process_friendship_request_type, agent message_handler_error_wrapper(agent l_user.user_process_friendship_request, ?)) register_main_loop_message_handler (user_namespace, user_remove_friendship_type, agent message_handler_error_wrapper(agent l_user.user_remove_friendship, ?)) register_main_loop_message_handler (user_namespace, user_list_friends_type, agent message_handler_error_wrapper(agent l_user.user_list_friends, ?)) register_main_loop_message_handler (user_namespace, user_send_message_type, agent message_handler_error_wrapper(agent l_user.user_send_message, ?)) register_main_loop_message_handler (user_namespace, user_disable_account_type, agent message_handler_error_wrapper(agent l_user.user_disable_account, ?)) register_main_loop_message_handler (user_namespace, user_list_communities_type, agent message_handler_error_wrapper(agent l_user.user_list_communities, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_subversion_configuration_type, agent message_handler_error_wrapper(agent l_user.svn_configuration, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_git_configuration_type, agent message_handler_error_wrapper(agent l_user.git_configuration, ?)) register_main_loop_message_handler (user_namespace, user_retrieve_ftp_configuration_type, agent message_handler_error_wrapper(agent l_user.ftp_configuration, ?)) register_main_loop_message_handler (origo_system_namespace, system_retrieve_all_email_type, agent message_handler_error_wrapper(agent l_user.mail_addresses, ?)) create l_project.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (project_namespace, project_create_type, agent message_handler_error_wrapper(agent l_project.project_create, ?)) register_main_loop_message_handler (project_namespace, project_remove_type, agent message_handler_error_wrapper (agent l_project.project_remove, ?)) register_main_loop_message_handler (project_namespace, project_retrieve_id_type, agent message_handler_error_wrapper(agent l_project.project_retrieve_id, ?)) register_main_loop_message_handler (project_namespace, project_id_type, agent message_handler_error_wrapper(agent l_project.project, ?)) register_main_loop_message_handler (project_namespace, project_change_group_type, agent message_handler_error_wrapper(agent l_project.project_change_group, ?)) register_main_loop_message_handler (project_namespace, project_list_of_user_type, agent message_handler_error_wrapper(agent l_project.project_list_of_user, ?)) register_main_loop_message_handler (project_namespace, project_members_type, agent message_handler_error_wrapper(agent l_project.project_members, ?)) register_main_loop_message_handler (project_namespace, project_change_description_type, agent message_handler_error_wrapper (agent l_project.project_change_description, ?)) register_main_loop_message_handler (project_namespace, project_change_logo_type, agent message_handler_error_wrapper (agent l_project.project_change_logo, ?)) register_main_loop_message_handler (project_namespace, project_list_bookmarkers_type, agent message_handler_error_wrapper (agent l_project.project_bookmarkers, ?)) register_main_loop_message_handler (project_namespace, project_internal_type, agent message_handler_error_wrapper(agent l_project.project_internal, ?)) register_main_loop_message_handler (project_namespace, project_request_add_type, agent message_handler_error_wrapper(agent l_project.project_request_add, ?)) register_main_loop_message_handler (project_namespace, project_request_retrieve_type, agent message_handler_error_wrapper(agent l_project.project_request_retrieve, ?)) register_main_loop_message_handler (project_namespace, project_list_communities_type, agent message_handler_error_wrapper(agent l_project.project_list_communities, ?)) register_main_loop_message_handler (project_namespace, project_retrieve_statistics_type, agent message_handler_error_wrapper(agent l_project.project_retrieve_statistics, ?)) register_main_loop_message_handler (project_namespace, project_change_settings_type, agent message_handler_error_wrapper(agent l_project.project_change_settings, ?)) register_main_loop_message_handler (project_namespace, project_retrieve_settings_type, agent message_handler_error_wrapper(agent l_project.project_retrieve_settings, ?)) register_main_loop_message_handler (project_namespace, project_retrieve_statistics_internal_type, agent message_handler_error_wrapper(agent l_project.project_retrieve_statistics, ?)) register_main_loop_message_handler (project_namespace, project_change_information_type, agent message_handler_error_wrapper(agent l_project.project_change_information, ?)) register_main_loop_message_handler (project_namespace, project_retrieve_information_type, agent message_handler_error_wrapper(agent l_project.project_retrieve_information, ?)) register_main_loop_message_handler (project_namespace, project_change_type_type, agent message_handler_error_wrapper(agent l_project.project_change_type, ?)) register_main_loop_message_handler (project_namespace, project_list_repositories_type, agent message_handler_error_wrapper(agent l_project.project_list_repositories, ?)) register_main_loop_message_handler (project_namespace, project_add_repository_type, agent message_handler_error_wrapper(agent l_project.project_add_repository, ?)) register_main_loop_message_handler (project_namespace, project_remove_repository_type, agent message_handler_error_wrapper(agent l_project.project_remove_repository, ?)) create l_workitem.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (workitem_namespace, workitem_count_type, agent message_handler_error_wrapper(agent l_workitem.workitem_count, ?)) register_main_loop_message_handler (workitem_namespace, workitem_list_type, agent message_handler_error_wrapper(agent l_workitem.workitem_list, ?)) register_main_loop_message_handler (workitem_namespace, workitem_new_activity_type, agent message_handler_error_wrapper(agent l_workitem.new_activity, ?)) register_main_loop_message_handler (workitem_namespace, workitem_retrieve_type, agent message_handler_error_wrapper(agent l_workitem.workitem_retrieve, ?)) register_main_loop_message_handler (workitem_namespace, workitem_mail_type, agent message_handler_error_wrapper(agent l_workitem.workitem_mail, ?)) register_main_loop_message_handler (workitem_namespace, workitem_set_read_status_type, agent message_handler_error_wrapper(agent l_workitem.workitem_set_read_status, ?)) register_main_loop_message_handler (workitem_namespace, workitem_set_read_status_project_type, agent message_handler_error_wrapper(agent l_workitem.workitem_set_read_status_project, ?)) create l_commit.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (commit_namespace, commit_add_type, agent message_handler_error_wrapper(agent l_commit.commit_add, ?)) create l_wiki.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (wiki_namespace, wiki_add_type, agent message_handler_error_wrapper(agent l_wiki.wiki_add, ?)) create l_comment.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (comment_namespace, comment_add_type, agent message_handler_error_wrapper(agent l_comment.comment_add, ?)) create l_blog.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (blog_namespace, blog_add_type, agent message_handler_error_wrapper(agent l_blog.blog_add, ?)) create l_issue.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (issue_namespace, issue_add_type, agent message_handler_error_wrapper(agent l_issue.issue_add, ?)) register_main_loop_message_handler (issue_namespace, issue_update_type, agent message_handler_error_wrapper(agent l_issue.issue_update, ?)) register_main_loop_message_handler (issue_namespace, issue_comment_type, agent message_handler_error_wrapper(agent l_issue.issue_comment, ?)) register_main_loop_message_handler (issue_namespace, issue_delete_type, agent message_handler_error_wrapper(agent l_issue.issue_delete, ?)) register_main_loop_message_handler (issue_namespace, issue_list_changed_type, agent message_handler_error_wrapper(agent l_issue.issue_list_changed, ?)) register_main_loop_message_handler (issue_namespace, issue_list_type, agent message_handler_error_wrapper(agent l_issue.issue_list, ?)) register_main_loop_message_handler (issue_namespace, issue_retrieve_type, agent message_handler_error_wrapper(agent l_issue.issue_retrieve, ?)) register_main_loop_message_handler (issue_namespace, issue_search_type, agent message_handler_error_wrapper(agent l_issue.issue_search, ?)) register_main_loop_message_handler (issue_namespace, issue_list_tags_type, agent message_handler_error_wrapper(agent l_issue.issue_list_tags, ?)) register_main_loop_message_handler (issue_namespace, issue_retrieve_planning_data_type, agent message_handler_error_wrapper (agent l_issue.issue_retrieve_planning_data, ?)) register_main_loop_message_handler (issue_namespace, issue_add_attachment_type, agent message_handler_error_wrapper (agent l_issue.issue_add_attachment, ?)) register_main_loop_message_handler (issue_namespace, issue_retrieve_attachments_type, agent message_handler_error_wrapper (agent l_issue.issue_retrieve_attachments, ?)) register_main_loop_message_handler (issue_namespace, issue_remove_attachment_type, agent message_handler_error_wrapper (agent l_issue.issue_remove_attachment, ?)) register_main_loop_message_handler (issue_namespace, issue_remove_all_attachments_type, agent message_handler_error_wrapper (agent l_issue.issue_remove_all_attachments, ?)) register_main_loop_message_handler (issue_namespace, issue_add_subscription_type, agent message_handler_error_wrapper (agent l_issue.issue_add_subscription, ?)) register_main_loop_message_handler (issue_namespace, issue_remove_subscription_type, agent message_handler_error_wrapper (agent l_issue.issue_remove_subscription, ?)) create l_release.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (release_namespace, release_add_type, agent message_handler_error_wrapper(agent l_release.release_add, ?)) register_main_loop_message_handler (release_namespace, release_list_type, agent message_handler_error_wrapper(agent l_release.release_list, ?)) register_main_loop_message_handler (release_namespace, release_retrieve_type, agent message_handler_error_wrapper(agent l_release.release_retrieve, ?)) register_main_loop_message_handler (release_namespace, release_list_internal_type, agent message_handler_error_wrapper(agent l_release.release_list_internal, ?)) register_main_loop_message_handler (release_namespace, release_retrieve_internal_type, agent message_handler_error_wrapper(agent l_release.release_retrieve_internal, ?)) register_main_loop_message_handler (release_namespace, release_delete_type, agent message_handler_error_wrapper(agent l_release.release_delete, ?)) create l_community.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (community_namespace, community_list_type, agent message_handler_error_wrapper(agent l_community.community_list, ?)) register_main_loop_message_handler (community_namespace, community_retrieve_type, agent message_handler_error_wrapper(agent l_community.community_retrieve, ?)) register_main_loop_message_handler (community_namespace, community_create_type, agent message_handler_error_wrapper (agent l_community.community_create, ?)) register_main_loop_message_handler (community_namespace, community_change_group_type, agent message_handler_error_wrapper (agent l_community.community_change_group, ?)) register_main_loop_message_handler (community_namespace, community_list_members_type, agent message_handler_error_wrapper (agent l_community.community_list_members, ?)) register_main_loop_message_handler (community_namespace, community_list_projects_type, agent message_handler_error_wrapper (agent l_community.community_list_projects, ?)) register_main_loop_message_handler (community_namespace, community_add_project_type, agent message_handler_error_wrapper (agent l_community.community_add_project, ?)) register_main_loop_message_handler (community_namespace, community_remove_project_type, agent message_handler_error_wrapper (agent l_community.community_remove_project, ?)) register_main_loop_message_handler (community_namespace, community_delete_type, agent message_handler_error_wrapper (agent l_community.community_delete, ?)) register_main_loop_message_handler (community_namespace, community_change_description_type, agent message_handler_error_wrapper (agent l_community.community_change_description, ?)) register_main_loop_message_handler (community_namespace, community_list_wiki_pages_type, agent message_handler_error_wrapper (agent l_community.community_list_wiki_pages, ?)) register_main_loop_message_handler (community_namespace, community_retrieve_wiki_page_type, agent message_handler_error_wrapper (agent l_community.community_retrieve_wiki_page, ?)) register_main_loop_message_handler (community_namespace, community_add_wiki_page_type, agent message_handler_error_wrapper (agent l_community.community_add_wiki_page, ?)) register_main_loop_message_handler (community_namespace, community_edit_wiki_page_type, agent message_handler_error_wrapper (agent l_community.community_edit_wiki_page, ?)) register_main_loop_message_handler (community_namespace, community_rename_wiki_page_type, agent message_handler_error_wrapper (agent l_community.community_rename_wiki_page, ?)) register_main_loop_message_handler (community_namespace, community_delete_wiki_page_type, agent message_handler_error_wrapper (agent l_community.community_delete_wiki_page, ?)) create l_statistics.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (statistics_namespace, statistics_retrieve_workitem_type, agent message_handler_error_wrapper (agent l_statistics.retrieve_workitem, ?)) register_main_loop_message_handler (statistics_namespace, statistics_retrieve_issue_type, agent message_handler_error_wrapper (agent l_statistics.retrieve_issue, ?)) create l_system.make (Current, l_db_handler, l_policy_cache) register_main_loop_message_handler (origo_system_namespace, system_retrieve_active_projects_type, agent message_handler_error_wrapper (agent l_system.retrieve_active_projects, ?)) end aranea_shutdown -- Called on shutdown. do -- if we have a cleanup timer, stop it if cleanup_timer /= Void then cleanup_timer.stop end end message_handler_error_wrapper (a_agent: PROCEDURE [ANY, TUPLE [A_MESSAGE]]; a_msg: A_MESSAGE) -- Wrapper around a message handler that catches some errors and returns a status message. require a_agent_set: a_agent /= Void local l_status_msg: A_GENERAL_STATUS_MESSAGE l_retried: BOOLEAN do if not l_retried then a_agent.call ([a_msg]) end rescue node_logger.fatal ("Exception while handling message: " + exception_trace) if is_developer_exception_of_name (except_database_error) then l_retried := True create l_status_msg.make (create {A_BOOLEAN_VALUE}.make (False), create {A_STRING_VALUE}.make (err_database_error)) send_message_reply (l_status_msg, a_msg) retry end end end