示例#1
0
    def __call__(self, **kwargs):
        self._load_factories()
        connections = {}
        factories = {}

        for context in self._context_map.contexts:
            storage = context.config.get('storage', {})
            if 'services' in storage:
                for name, config in storage.get('services').items():
                    config = config or {}
                    if name not in self._connection_factories and config.get('type') not in self._connection_factories:
                        raise ffd.ConfigurationError(f"No ConnectionFactory configured for '{name}'")
                    key = name if name in self._connection_factories else config.get('type')
                    connections[name] = context.container.build(self._connection_factories[key])(
                        **(config.get('connection') or {})
                    )

        for context in self._context_map.contexts:
            storage = context.config.get('storage', {})
            if 'services' in storage:
                for name, config in storage.get('services').items():
                    config = config or {}
                    if name not in self._repository_factories and config.get('type') not in self._repository_factories:
                        raise ffd.ConfigurationError(f"No RepositoryFactory configured for '{name}'")
                    key = name if name in self._repository_factories else config.get('type')
                    factory = context.container.autowire(self._repository_factories[key])
                    try:
                        factories[name] = factory(connections[name], **(config.get('repository') or {}))
                    except TypeError as e:
                        if '__init__() takes exactly one argument' in str(e):
                            raise ffd.FrameworkError(f"{factory.__name__}.__init__() must take a connection as "
                                                     f"the first argument")
                        raise e

        for context in self._context_map.contexts:
            if context.name == 'firefly':
                continue
            storage = context.config.get('storage', {})
            registered_aggregates = []
            if 'aggregates' in storage:
                for entity, service in storage.get('aggregates').items():
                    if not entity.startswith(context.name):
                        entity = f'{context.name}.{entity}'
                    entity = ffd.load_class(entity)
                    registered_aggregates.append(entity)
                    self._registry.register_factory(entity, factories[service])
            if 'default' in storage:
                for entity in context.entities:
                    if issubclass(entity, ffd.AggregateRoot) and entity is not ffd.AggregateRoot \
                            and entity not in registered_aggregates:
                        self._registry.register_factory(entity, factories[storage.get('default')])

        # TODO Get persistence working in these core services.
        # self._registry(ffd.ContextMap).add(self._context_map)

        self.dispatch(ffd.StorageConfigured())
示例#2
0
 def path_constructor(_, node):
     value = node.value
     match = path_matcher.match(value)
     env_var = match.groups()[1]
     if env_var not in os.environ:
         raise ffd.ConfigurationError(f'Environment variable {env_var} is used in config, but is not set')
     return str(value).replace(f'${{{env_var}}}', os.environ.get(env_var))
示例#3
0
    def __call__(self, message: ffd.Message, next_: Callable) -> ffd.Message:
        if not self._initialized:
            self._initialize()

        not_for_this_context = message.get_context() != 'firefly' and \
                               self._context_map.get_context(message.get_context()) is None
        is_async = hasattr(message, '_async') and getattr(message, '_async') is True

        if not_for_this_context or is_async:
            return self._transfer_message(message)

        args = message.to_dict()
        args['_message'] = message

        if str(message) not in self._command_handlers:
            raise ffd.ConfigurationError(f'No command handler registered for {message}')

        service = self._command_handlers[str(message)]

        if self._service_is_batch_capable(service) and self._batch_service.is_registered(service.__class__):
            self.debug('Deferring to batch service')
            return self._batch_service.handle(service, args)
        else:
            parsed_args = ffd.build_argument_list(args, service)
            self.debug('Calling service %s with arguments: %s', service, parsed_args)
            return service(**parsed_args)
示例#4
0
    def configure(self, cls: Any, container):
        if not issubclass(cls, ffd.ApplicationService):
            raise ffd.ConfigurationError(
                '@batch_processor must be used on an ApplicationService')

        container.batch_service.register(
            cls,
            batch_size=getattr(cls, '_batch_size'),
            batch_window=getattr(cls, '_batch_window'),
            message_type='command' if cls.is_command_handler() else 'event',
            message=cls.get_command()
            if cls.is_command_handler() else cls.get_events()[0])
示例#5
0
    def _ensure_connected(self):
        if self._connection is not None:
            return

        try:
            host = self._config['host']
        except KeyError:
            raise ffd.ConfigurationError(
                f'host is required in sqlite_storage_interface')

        self._connection = sqlite3.connect(
            host, detect_types=sqlite3.PARSE_DECLTYPES)
        self._connection.row_factory = sqlite3.Row
示例#6
0
    def __call__(self, message: ffd.Message, next_: Callable) -> ffd.Message:
        if not self._initialized:
            self._initialize()

        # TODO Fix the local dev server to work with multiple contexts
        if self._context is not None and message.get_context() != 'firefly' and message.get_context() != self._context:
            return self._transfer_message(message)

        args = message.to_dict()
        args['_message'] = message
        for service, query_type in self._query_handlers.items():
            if message.is_this(query_type):
                return service(**ffd.build_argument_list(args, service))
        raise ffd.ConfigurationError(f'No query handler registered for {message}')
示例#7
0
    def __call__(self, message: ffd.Message, next_: Callable) -> ffd.Message:
        if not self._initialized:
            self._initialize()

        if message.get_context() != 'firefly' and self._context_map.get_context(message.get_context()) is None:
            return self._transfer_message(message)

        args = message.to_dict()
        args['_message'] = message
        for service, query_type in self._query_handlers.items():
            if message.is_this(query_type):
                parsed_args = ffd.build_argument_list(args, service)
                self.debug('Calling service with arguments: %s', parsed_args)
                return service(**parsed_args)
        raise ffd.ConfigurationError(f'No query handler registered for {message}')
示例#8
0
    def __call__(self, message: ffd.Message, next_: Callable) -> ffd.Message:
        if not self._initialized:
            self._initialize()

        # TODO Fix the local dev server to work with multiple contexts
        if self._context is not None and message.get_context(
        ) != 'firefly' and message.get_context() != self._context:
            return self._transfer_message(message)

        args = message.to_dict()
        args['_message'] = message

        if str(message) not in self._command_handlers:
            raise ffd.ConfigurationError(
                f'No command handler registered for {message}')

        service = self._command_handlers[str(message)]

        return service(**ffd.build_argument_list(args, service))
 def get(self, name: str) -> Type[ffi.RdbStorageInterface]:
     if name not in self._interfaces:
         raise ffd.ConfigurationError(f'Storage interface with name "{name}" is not registered')
     return self._interfaces.get(name)
示例#10
0
 def configure(self, cls: Any, container):
     if not issubclass(cls, ffd.Handler):
         raise ffd.ConfigurationError(
             'Authorizers must be a subclass of Handler')
     container.authorizer.add(container.build(cls))