def setUp(self):
        super(TestFNatsServer, self).setUp()

        self.subject = "foo"
        self.mock_nats_client = mock.Mock()
        self.mock_processor = mock.Mock()
        self.mock_transport_factory = mock.Mock()
        self.mock_prot_factory = mock.Mock()

        self.server = FNatsServer(self.mock_nats_client, self.subject,
                                  self.mock_processor, self.mock_prot_factory)
        self.server._iprot_factory = mock.Mock()
        self.server._oprot_factory = mock.Mock()
Beispiel #2
0
def main():
    # Declare the protocol stack used for serialization.
    # Protocol stacks must match between clients and servers.
    prot_factory = FProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory())

    # Open a NATS connection to receive requests
    nats_client = NATS()
    options = {"verbose": True, "servers": ["nats://127.0.0.1:4222"]}

    yield nats_client.connect(**options)

    # Create a new server processor.
    # Incoming requests to the processor are passed to the handler.
    # Results from the handler are returned back to the client.
    processor = FStoreProcessor(StoreHandler())

    # Create a new music store server using the processor,
    # The server will listen on the music-service NATS topic
    server = FNatsServer(nats_client, "music-service", processor, prot_factory)

    root.info("Starting server...")

    yield server.serve()
Beispiel #3
0
def main():
    parser = argparse.ArgumentParser(description="Run a tornado python server")
    parser.add_argument('--port', dest='port', default='9090')
    parser.add_argument('--protocol',
                        dest='protocol_type',
                        default="binary",
                        choices="binary, compact, json")
    parser.add_argument('--transport',
                        dest="transport_type",
                        default="stateless",
                        choices="stateless, http")

    args = parser.parse_args()

    if args.protocol_type == "binary":
        protocol_factory = FProtocolFactory(TBinaryProtocolFactory())
    elif args.protocol_type == "compact":
        protocol_factory = FProtocolFactory(TCompactProtocolFactory())
    elif args.protocol_type == "json":
        protocol_factory = FProtocolFactory(TJSONProtocolFactory())
    else:
        logging.error("Unknown protocol type: %s", args.protocol_type)
        sys.exit(1)

    nats_client = NATS()
    options = {"verbose": True, "servers": ["nats://127.0.0.1:4222"]}
    yield nats_client.connect(**options)

    global port
    port = args.port

    handler = FrugalTestHandler()
    subject = "frugal.*.*.rpc.{}".format(args.port)
    processor = Processor(handler)

    if args.transport_type == "stateless":
        server = FNatsServer(nats_client, [subject], processor,
                             protocol_factory)

        # start healthcheck so the test runner knows the server is running
        thread.start_new_thread(healthcheck, (port, ))
        print("Starting {} server...".format(args.transport_type))
        yield server.serve()

    elif args.transport_type == "http":
        factories = {
            'processor': processor,
            'protocol_factory': protocol_factory
        }

        server = Application([(r'/', FHttpHandler, factories)])

        print("Starting {} server...".format(args.transport_type))
        server.listen(port)

    else:
        logging.error("Unknown transport type: %s", args.transport_type)
        sys.exit(1)

    # Setup subscriber, send response upon receipt
    pub_transport_factory = FNatsPublisherTransportFactory(nats_client)
    sub_transport_factory = FNatsSubscriberTransportFactory(nats_client)
    provider = FScopeProvider(pub_transport_factory, sub_transport_factory,
                              protocol_factory)
    global publisher
    publisher = EventsPublisher(provider)
    yield publisher.open()

    @gen.coroutine
    def response_handler(context, event):
        print("received {} : {}".format(context, event))
        preamble = context.get_request_header(PREAMBLE_HEADER)
        if preamble is None or preamble == "":
            logging.error("Client did not provide preamble header")
            return
        ramble = context.get_request_header(RAMBLE_HEADER)
        if ramble is None or ramble == "":
            logging.error("Client did not provide ramble header")
            return
        response_event = Event(Message="Sending Response")
        response_context = FContext("Call")
        global publisher
        global port
        yield publisher.publish_EventCreated(response_context, preamble,
                                             ramble, "response",
                                             "{}".format(port), response_event)
        print("Published event={}".format(response_event))

    subscriber = EventsSubscriber(provider)
    yield subscriber.subscribe_EventCreated("*", "*", "call",
                                            "{}".format(args.port),
                                            response_handler)
class TestFNatsServer(AsyncTestCase):

    def setUp(self):
        super(TestFNatsServer, self).setUp()

        self.subject = "foo"
        self.mock_nats_client = mock.Mock()
        self.mock_processor = mock.Mock()
        self.mock_transport_factory = mock.Mock()
        self.mock_prot_factory = mock.Mock()

        self.server = FNatsServer(
            self.mock_nats_client,
            self.subject,
            self.mock_processor,
            self.mock_prot_factory
        )
        self.server._iprot_factory = mock.Mock()
        self.server._oprot_factory = mock.Mock()

    @gen_test
    def test_serve(self):
        f = concurrent.Future()
        f.set_result(123)
        self.mock_nats_client.subscribe_async.return_value = f

        yield self.server.serve()

        self.assertEquals([123], self.server._sub_ids)

    @gen_test
    def test_stop(self):
        self.server._sub_ids = [123]
        f = concurrent.Future()
        f.set_result(None)
        self.mock_nats_client.unsubscribe.return_value = f

        yield self.server.stop()

        self.mock_nats_client.unsubscribe.assert_called_with(123)

    @gen_test
    def test_on_message_callback_no_reply_returns_early(self):
        data = b'asdf'
        frame_size = struct.pack('!I', len(data))
        msg = TestMsg(subject='test', reply='', data=frame_size + data)

        yield self.server._on_message_callback(msg)

        assert not self.server._iprot_factory.get_protocol.called
        assert not self.server._oprot_factory.get_protocol.called
        assert not self.server._processor.process.called

    @mock.patch('frugal.tornado.server.nats_server._NATS_MAX_MESSAGE_SIZE', 6)
    @gen_test
    def test_on_message_callback_bad_framesize_returns_early(self):
        data = b'asdf'
        frame_size = struct.pack('!I', len(data))
        msg = TestMsg(subject='test', reply='reply', data=frame_size + data)

        yield self.server._on_message_callback(msg)

        assert not self.server._iprot_factory.get_protocol.called
        assert not self.server._oprot_factory.get_protocol.called
        assert not self.server._processor.process.called

    @gen_test
    def test_on_message_callback_calls_process(self):
        iprot = BytesIO()
        oprot = BytesIO()
        self.server._iprot_factory.get_protocol.return_value = iprot
        self.server._oprot_factory.get_protocol.return_value = oprot

        data = b'asdf'
        frame_size = struct.pack('!I', len(data))

        msg = TestMsg(subject="foo", reply="inbox", data=frame_size + data)
        publish_future = concurrent.Future()
        publish_future.set_result(None)
        self.mock_nats_client.publish.return_value = publish_future

        process_future = concurrent.Future()
        process_future.set_result(None)
        self.mock_processor.process.return_value = process_future

        yield self.server._on_message_callback(msg)

        self.server._processor.process.assert_called_with(iprot, oprot)