54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
from colony.core.logger.logging import get_logger
|
|
|
|
|
|
def parse_command(payload):
|
|
command = payload.get("command") if isinstance(payload, dict) else None
|
|
if not isinstance(command, dict):
|
|
raise ValueError("Payload has no command")
|
|
|
|
role_name = command.get("role")
|
|
command_name = command.get("name")
|
|
if not isinstance(role_name, str) or not role_name or not isinstance(command_name, str) or not command_name:
|
|
raise ValueError("Command needs a role and a name")
|
|
|
|
args = command.get("args")
|
|
if args is None:
|
|
args = []
|
|
kwargs = command.get("kwargs")
|
|
if kwargs is None:
|
|
kwargs = {}
|
|
if not isinstance(args, (list, tuple)) or not isinstance(kwargs, dict):
|
|
raise ValueError("Command args must be a list and kwargs a dict")
|
|
|
|
caller_id = command.get("from")
|
|
if not isinstance(caller_id, str):
|
|
caller_id = None
|
|
|
|
return role_name, command_name, tuple(args), kwargs, caller_id
|
|
|
|
|
|
class Dispatcher:
|
|
def __init__(self, network, role_registry):
|
|
self.logger = get_logger(self.__class__.__name__)
|
|
|
|
self.network = network
|
|
self.role_registry = role_registry
|
|
|
|
def dispatch(self, payload):
|
|
role_name, command_name, args, kwargs, caller_id = parse_command(payload)
|
|
self.logger.debug(f"Dispatching payload for command {role_name}.{command_name}")
|
|
|
|
role_entry = self.role_registry.get_role_class_by_name(role_name)
|
|
if role_entry is None:
|
|
raise ValueError(f"Unknown role {role_name}")
|
|
|
|
commands_enum = role_entry.COMMANDS
|
|
command = commands_enum(f"{role_name}.{command_name}")
|
|
|
|
node = self.network.get_self()
|
|
|
|
self.logger.info(f"Executing {role_name}.{command_name} on local node {node.id}")
|
|
result = node.execute_local(command, *args, caller_id=caller_id, **kwargs)
|
|
self.logger.debug(f"Passing the results from {role_name}.{command_name}")
|
|
return result
|