class Connector(object): """The Connector See module description for more context. """ REQUIRED_KEYS = {"name", "mapping", "message"} RECEIVER_NAME = "bm-connector" def __init__(self, config=None): """Initialise the Connector and starts to listen to incoming messages. :param config: Configuration to use (default config if None). """ self.log = logging.getLogger(self.__class__.__name__) if config is None: config = ConnConfig() self.log.info("Falling back to default configuration.") # errors up to here are allowed to terminate the program mappings = self._read_mappings(config.mappings) self.mapper = Mapper(mappings) self.log.debug("Mappings read.") self.sender = Sender(config.send.address, config.send.port, config.broker.endpoint_prefix + config.connector_id, config.broker.topic, config.connector_id) self.log.info("Sender created.") self.receiver = Receiver(self.RECEIVER_NAME, config.listen.address, config.listen.port) self.log.info("Receiver created.") self.receiver.listen("/", self.handle_receive) def _read_mappings(self, location): """Read the mappings into a list of dictionaries.""" # os/fs errors here are allowed to terminate the program # yaml parse errors should not crash but log mappings = [] for root, _, files in walk(location): for f in files: filepath = os.path.join(root, f) with open(filepath, "r") as fd: # TODO extract the below block? try: mp = yaml.load(fd) for i in self.REQUIRED_KEYS: if i not in mp: raise LookupError(i) mappings.append(mp) except LookupError as e: self.log.error( "Missing key '{}' in file '{}'. Ignoring." .format(e.args[0], filepath)) except Exception: # TODO find correct exception types. self.log.error( "Failed to read mapping in '{}'. Ignoring." .format(filepath)) return mappings def handle_receive(self, message): """Handle message via mapping. :param message: The message to map and send. (json) """ mapped = self.mapper.transform(message) if mapped: self.log.info("Mapped message is '{}'.".format(mapped)) self.sender.send(mapped)
def launch_receiver(coder): receiver = Receiver(coder=coder) receiver.listen()