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())
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))
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)
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])
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
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}')
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}')
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)
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))