indexing description: "Origo Core Node" license: "MIT license (see ../../license.txt)" author: "Beat Strasser " date: "$Date$" revision: "$Revision$" class O_NODE_CORE inherit O_NODE redefine make_node, load_services, configure_loaded_peer_platform, main, stop end O_LOOKUP_CONSTANTS P2P_CREATORS_SHARED create make feature {NONE} -- Initialization make_node is -- Create specific node do if argument (2).is_integer then xmlrpc_port := argument (2).to_integer Precursor else io.put_string ("Usage: " + argument (0) + " ConfigDirectory Port") io.new_line end end load_services is -- Load local services do -- Initialize XML RPC server create xmlrpc.make (xmlrpc_port, logger) -- Load lookup proxy service create start_lookup_proxy_flag.make_empty create lookup_proxy.make (start_lookup_proxy_flag, lookup_advertisement, logger) xmlrpc.registry.register (lookup_proxy, lookup_service_name) end configure_loaded_peer_platform is -- Additional configuration steps after platform has been loaded local lookup_proxy_adv: O_SERVICE_ROLE_ADVERTISEMENT do Precursor -- get peer module instance peer_module ?= opg.lookup_module (p2p_module_name) check Peer_module_loaded: peer_module /= Void end -- register lookup configuration creator xml_document_creator.extend_custom_creator ("OrigoLookupMainConfig", agent (a_root: XM_ELEMENT): O_LOOKUP_SERVICE_CONFIGURATION do create Result.make_from_element (a_root) end) -- register handlers peer_module.extend_core_event_handler (agent network_event_handler) -- create lookup proxy advertisement create lookup_proxy_adv.make (opg.peer_id, lookup_service_type, lookup_service_name, lookup_service_proxy_role, {O_SERVICE_ROLE_ADVERTISEMENT}.status_initialized) lookup_proxy.extend_role (lookup_proxy_adv) -- register service lookup_proxy.register (peer_module) logger.info ("Services loaded and configured") end main is -- Main routine local failed: BOOLEAN do if not failed then -- wait until lookup proxy service is requested to start. -- unfortunately, we did not succeed to register the lookup server -- after the xmlrpc has been started, so we do it here from until start_lookup_proxy_flag.count > 0 loop sleep (500000000) end logger.info ("Starting XML RPC server now") xmlrpc.run end logger.fatal ("XML RPC server crashed") rescue failed := True retry end stop is -- Stop node do -- unregister service if lookup_proxy /= Void and lookup_proxy.p2p_module /= Void then lookup_proxy.unregister end -- stop network Precursor peer_module := Void end feature -- Access is_core: BOOLEAN is True xmlrpc_port: INTEGER xmlrpc: O_XMLRPC_SERVER lookup_proxy: O_LOOKUP_SERVICE_PROXY Peer_name: STRING is -- Core's peer name. Cores are discovered by this name. do Result := core_peer_name end Peer_description: STRING is -- Node's peer description do Result := core_peer_name end expected_argument_count: INTEGER is 2 -- Number of expected arguments feature {NONE} -- Implementation peer_module: O_P2P_MODULE start_lookup_proxy_flag: STRING network_event_handler (a_msg: O_SERVICE_CONTROL_MESSAGE) is -- Process network event do inspect a_msg.control_command when {O_SERVICE_CONTROL_MESSAGE}.command_received_service_configurations then logger.info ("Received service configurations") handle_configurations (a_msg.parameters) when {O_SERVICE_CONTROL_MESSAGE}.command_unregister_service then logger.info ("Received unregister service") unregister_service (a_msg.parameters.first) else -- not handled end end handle_configurations (a_list: DS_LIST [STRING]) is -- Handle incoming configurations require List_valid: a_list /= Void local sadv: O_SERVICE_ADVERTISEMENT role_cursor: DS_LIST_CURSOR [STRING] radv: O_SERVICE_ROLE_ADVERTISEMENT missing_role: BOOLEAN start_msg: O_SERVICE_CONTROL_MESSAGE do from a_list.start until a_list.after loop -- get advertisement with given unique id sadv ?= opg.discovery_service.local_general_advertisement (a_list.item_for_iteration) if sadv /= Void then -- check if all service roles for the current service are available from role_cursor := sadv.roles.new_cursor role_cursor.start until missing_role or role_cursor.after loop radv ?= opg.discovery_service.local_general_advertisement ("OrigoServiceRoleAdvertisement/" + sadv.type.out + "/" + sadv.name + "/" + role_cursor.item) if radv = Void or radv.status /= radv.status_initialized then missing_role := True end role_cursor.forth end if not missing_role then -- all roles available, send start request for entire service logger.info ("Sending start request for fully available service: " + sadv.type.out + "/" + sadv.name) create start_msg.make ({O_SERVICE_CONTROL_MESSAGE}.command_request_status_start) start_msg.set_service_type (sadv.type) start_msg.set_service_name (sadv.name) peer_module.send_message (start_msg) end end a_list.forth end end unregister_service (a_service: STRING) is -- Flush all advertisements from `a_service' require Service_valid: a_service /= Void local sadv: O_SERVICE_ADVERTISEMENT role_cursor: DS_LIST_CURSOR [STRING] do -- get advertisement with given unique id sadv ?= opg.discovery_service.local_general_advertisement (a_service) if sadv /= Void then -- flush all role advertisements from role_cursor := sadv.roles.new_cursor role_cursor.start until role_cursor.after loop opg.discovery_service.flush_general_advertisement (a_service + "/" + role_cursor.item) role_cursor.forth end -- flush service advertisement opg.discovery_service.flush_general_advertisement (a_service) logger.info ("Flushed service advertisement: " + a_service) end end end