class FlaskHttpListenerClient(ListenerClient):
    """Flask client to receive messages from customer app."""
    def __init__(self, config: dict):  # pragma: no cover
        """
        Use a flask server as the listener.

        Configuration keys:

            PORT
            HOST
        """
        self.port = int(config['PORT']) if 'PORT' in config else None
        self.host = config.get('HOST', DEFAULT_HOST)
        self.on_message_received = None
        self.t_flask = None
        self.logger = Logger()

    def run_flask_server(self):  # pragma: no cover
        """Run the flask server."""
        app = Flask(__name__)

        @app.route("/", methods=["POST"])
        def on_input():  # pylint: disable=unused-variable
            msg = str(request.data, 'utf-8', 'ignore')
            if self.on_message_received(msg):
                return 'msg: %s' % msg

            print(
                'Error: The callback failed to process the message, returning 500'
            )
            return 'Error: The callback failed to process the message', 500

        app.run(host=self.host,
                port=self.port,
                debug=False,
                use_reloader=False,
                threaded=True)

    def start(self, on_message_received):  # pragma: no cover
        self.on_message_received = on_message_received
        self.t_flask = threading.Thread(name='agogosml',
                                        target=self.run_flask_server)
        self.t_flask.setDaemon(True)
        self.logger.event('flask.server.start', {
            'port': str(self.port),
            'host': self.host
        })
        self.t_flask.start()

    def stop(self):  # pragma: no cover
        try:
            func = request.environ.get('werkzeug.server.shutdown')
            if func is None:
                raise RuntimeError('Not running with the Werkzeug Server')
            func()
        except Exception as ex:
            print('error while shutting down flask server: %s' % ex)
Example #2
0
class OutputWriter:
    """OutputWriter class."""

    def __init__(self, streaming_client: AbstractStreamingClient,
                 listener: ListenerClient):
        """Accept incoming messages and route them to a configured output."""
        self.messaging_client = streaming_client
        self.listener = listener
        self.logger = Logger()

    def on_message_received(self, message: str) -> bool:
        """Send messages onwards to a streaming client."""
        success = self.messaging_client.send(message)
        self.logger.event('output.message.received', {'success': str(success)})
        return success

    def start_incoming_messages(self, callback: Optional[Callable[[str], bool]] = None):
        """Start accepting messages."""
        self.logger.event('output.lifecycle.start')
        self.listener.start(callback or self.on_message_received)

    def stop_incoming_messages(self):
        """Stop accepting messages."""
        self.listener.stop()
        self.logger.event('output.lifecycle.stop')
Example #3
0
class InputReader:
    """InputReader."""

    def __init__(self, streaming_client: AbstractStreamingClient, message_sender: MessageSender):
        """Accept an incoming message and route them to a configured output."""
        self.message_sender = message_sender
        self.messaging_client = streaming_client
        self.logger = Logger()

    def start_receiving_messages(self):
        """Start receiving messages from streaming endpoint."""
        self.logger.event('input.lifecycle.start')
        self.messaging_client.start_receiving(self.on_message_received)

    def stop_incoming_messages(self):
        """Stop incoming messages from streaming endpoint."""
        self.messaging_client.stop()
        self.logger.event('input.lifecycle.stop')

    def on_message_received(self, message: str) -> bool:
        """Send messages onwards."""
        result = self.message_sender.send(message)
        if result:
            success = True
        else:
            success = False
            self.handle_send_failure(message)
        self.logger.event('input.message.received', {'success': str(success)})
        return success

    def handle_send_failure(self, message: str):
        """Handle message send failure."""
        self.logger.error('Error while sending message to App %s', message)