Ejemplo n.º 1
0
class QueryService:

    def __init__(self, logger=None):
        self.running = False
        self.logger = Logger("regquery")
        self.logger.writeDebug('Running QueryService')
        # HTTPS under test only at present
        # enabled = Use HTTPS only in all URLs and mDNS adverts
        # disabled = Use HTTP only in all URLs and mDNS adverts
        # mixed = Use HTTP in all URLs, but additionally advertise an HTTPS endpoint for discovery of this API only
        self.config = {"priority": 100, "https_mode": "disabled"}
        self._load_config()
        self.mdns = MDNSEngine()
        self.httpServer = HttpServer(QueryServiceAPI, WS_PORT, '0.0.0.0', api_args=[self.logger, self.config])

    def start(self):
        if self.running:
            gevent.signal(signal.SIGINT,  self.sig_handler)
            gevent.signal(signal.SIGTERM, self.sig_handler)

        self.running = True
        self.mdns.start()

        self.logger.writeDebug('Running web socket server on %i' % WS_PORT)

        self.httpServer.start()

        while not self.httpServer.started.is_set():
            self.logger.writeDebug('Waiting for httpserver to start...')
            self.httpServer.started.wait()

        if self.httpServer.failed is not None:
            raise self.httpServer.failed

        self.logger.writeDebug("Running on port: {}".format(self.httpServer.port))

        priority = self.config["priority"]
        if not str(priority).isdigit() or priority < 100:
            priority = 0

        if self.config["https_mode"] != "enabled":
            self.mdns.register(DNS_SD_NAME + "_http", DNS_SD_TYPE, DNS_SD_HTTP_PORT,
                               {"pri": priority,
                                "api_ver": ",".join(API_VERSIONS),
                                "api_proto": "http"})
        if self.config["https_mode"] != "disabled":
            self.mdns.register(DNS_SD_NAME + "_https", DNS_SD_TYPE, DNS_SD_HTTPS_PORT,
                               {"pri": priority,
                                "api_ver": ",".join(API_VERSIONS),
                                "api_proto": "https"})

    def run(self):
        self.running = True
        self.start()
        while self.running:
            time.sleep(1)
        self._cleanup()

    def _cleanup(self):
        self.mdns.stop()
        self.mdns.close()
        self.httpServer.stop()

    def sig_handler(self):
        self.stop()

    def stop(self):
        self.running = False

    def _load_config(self):
        try:
            config_file = "/etc/ips-regquery/config.json"
            if os.path.isfile(config_file):
                f = open(config_file, 'r')
                extra_config = json.loads(f.read())
                self.config.update(extra_config)
        except Exception as e:
            self.logger.writeDebug("Exception loading config: {}".format(e))
Ejemplo n.º 2
0
class TestMDNSEngine(unittest.TestCase):
    def setUp(self):
        self.dut = MDNSEngine()
        self.dut.registrationController = MagicMock()
        self.name = "192.168.0.1_nmos-node._tcp.local."
        self.type = "_nmos-node._tcp"
        self.port = 8080

    def _helper_build_callback_handler(self):
        callbackHandler = MagicMock()
        callbackHandler.entryCollision = MagicMock()
        callbackHandler.entryFailed = MagicMock()
        callbackHandler.entryEstablished = MagicMock()
        return callbackHandler

    def test_add_registration_handle_errors_zeroconf_collision(self):
        thrower = self.dut.registrationController.addRegistration = MagicMock()
        thrower.side_effect = zeroconf.NonUniqueNameException
        callbackHandler = self._helper_build_callback_handler()
        self.dut._add_registration_handle_errors(MagicMock(), callbackHandler)
        self.assertTrue(callbackHandler.entryCollision.called)

    def test_add_registration_handle_errors_internal_collision(self):
        thrower = self.dut.registrationController.addRegistration = MagicMock()
        thrower.side_effect = ServiceAlreadyExistsException
        callbackHandler = self._helper_build_callback_handler()
        self.dut._add_registration_handle_errors(MagicMock(), callbackHandler)
        self.assertTrue(callbackHandler.entryCollision.called)

    def test_add_registration_handle_errors_fail(self):
        thrower = self.dut.registrationController.addRegistration = MagicMock()
        thrower.side_effect = zeroconf.Error
        callbackHandler = self._helper_build_callback_handler()
        self.dut._add_registration_handle_errors(MagicMock(), callbackHandler)
        self.assertTrue(callbackHandler.entryFailed.called)

    def test_add_registration_handle_errors_ok(self):
        callbackHandler = self._helper_build_callback_handler()
        self.dut._add_registration_handle_errors(MagicMock(), callbackHandler)
        self.assertTrue(callbackHandler.entryEstablished.called)

    def test_catch_interface_exception(self):
        with patch('nmoscommon.mdns.mdnsEngine.MDNSRegistration'):
            with patch(
                    'nmoscommon.mdns.mdnsEngine.MDNSAdvertisementCallbackHandler'
            ) as callbackHandler:
                self.dut._autostart_if_required = MagicMock()
                callback = callbackHandler.return_value = MagicMock()
                self.dut._add_registration_handle_errors = MagicMock()
                callback.entryFailed = MagicMock()
                self.dut.interfaceController = MagicMock()
                self.dut.interfaceController.getInterfaces = MagicMock()
                self.dut.interfaceController.getInterfaces.side_effect = InterfaceNotFoundException
                self.dut.register(None, None, None, None)
                self.assertTrue(callback.entryFailed.called)

    """The class should roll with it if not explicitly started before registering"""

    def test_implicit_start_register(self):
        self.dut.register(self.name, self.type, self.port, {})

    def test_implicit_start_update(self):
        with patch('nmoscommon.mdns.mdnsEngine.MDNSRegistrationController'):
            self.dut.update(self.name, self.type, txtRecord={})

    def helper_mock_registration_controller(self):
        registration = MagicMock()
        registration.update = MagicMock()
        controller = MagicMock()
        controller.__getitem__.side_effect = TypeError
        controller.registrations = {self.type: {self.name: registration}}
        controller.update = MagicMock()
        return controller

    def test_update_normal(self):
        self.dut.start()
        self.dut.registrationController = self.helper_mock_registration_controller(
        )
        regMock = self.dut.registrationController.registrations[self.type][
            self.name]
        self.dut.update(self.name, self.type, {})
        self.assertTrue(regMock.update.called)

    def test_update_record_not_found(self):
        self.dut.start()
        with self.assertRaises(ServiceNotFoundException):
            self.dut.update("not", "this")

    def test_disable_mdns_discover(self):
        with patch('nmoscommon.mdns.mdnsEngine.MDNSListener') as listener:
            self.dut.config = {"mdns_discover": False}
            callbackHandler = self._helper_build_callback_handler()
            self.dut._add_registration_handle_errors(MagicMock(),
                                                     callbackHandler)
            listener.assert_not_called()

    def test_disable_dns_discover(self):
        with patch('nmoscommon.mdns.mdnsEngine.DNSServiceController'
                   ) as controller:
            self.dut.config = {"dns_discover": False}
            callbackHandler = self._helper_build_callback_handler()
            self.dut._add_registration_handle_errors(MagicMock(),
                                                     callbackHandler)
            controller.assert_not_called()
class QueryService:
    def __init__(self, logger=None):
        self.running = False
        self.logger = Logger("regquery")
        self.logger.writeDebug('Running QueryService')
        self.config = {"priority": 0}
        self._load_config()
        self.mdns = MDNSEngine()
        self.httpServer = HttpServer(QueryServiceAPI,
                                     WS_PORT,
                                     '0.0.0.0',
                                     api_args=[self.logger])

    def start(self):
        if self.running:
            gevent.signal(signal.SIGINT, self.sig_handler)
            gevent.signal(signal.SIGTERM, self.sig_handler)

        self.running = True
        self.mdns.start()

        HOST = getLocalIP()

        self.logger.writeDebug('Running web socket server on %i' % WS_PORT)

        self.httpServer.start()

        while not self.httpServer.started.is_set():
            self.logger.writeDebug('Waiting for httpserver to start...')
            self.httpServer.started.wait()

        if self.httpServer.failed is not None:
            raise self.httpServer.failed

        self.logger.writeDebug("Running on port: {}".format(
            self.httpServer.port))

        priority = self.config["priority"]
        if not str(priority).isdigit() or priority < 100:
            priority = 0

        self.mdns.register('query_' + str(HOST), '_nmos-query._tcp',
                           DNS_SD_PORT, {
                               "pri": priority,
                               "api_ver": "v1.0,v1.1,v1.2",
                               "api_proto": "http"
                           })

    def run(self):
        self.running = True
        self.start()
        while self.running:
            time.sleep(1)
        self._cleanup()

    def _cleanup(self):
        self.mdns.stop()
        self.mdns.close()
        self.httpServer.stop()

    def sig_handler(self):
        self.stop()

    def stop(self):
        self.running = False

    def _load_config(self):
        try:
            config_file = "/etc/nmos-query/config.json"
            if os.path.isfile(config_file):
                f = open(config_file, 'r')
                extra_config = json.loads(f.read())
                self.config.update(extra_config)
        except Exception as e:
            self.logger.writeDebug("Exception loading config: {}".format(e))
class RegistryAggregatorService(object):
    def __init__(self, logger=None, interactive=False):
        self.config      = {"priority": 0}
        self._load_config()
        self.running     = False
        self.httpServer  = None
        self.interactive = interactive
        self.mdns        = MDNSEngine()
        self.logger      = Logger("aggregation", logger)

    def _load_config(self):
        try:
            config_file = "/etc/nmos-registration/config.json"
            if os.path.isfile(config_file):
                f = open(config_file, 'r')
                extra_config = json.loads(f.read())
                self.config.update(extra_config)
        except Exception as e:
            print "Exception loading config: {}".format(e)

    def start(self):
        if self.running:
            gevent.signal(signal.SIGINT,  self.sig_handler)
            gevent.signal(signal.SIGTERM, self.sig_handler)

        self.mdns.start()

        self.httpServer = HttpServer(AggregatorAPI, SERVICE_PORT, '0.0.0.0', api_args=[self.logger, self.config])
        self.httpServer.start()
        while not self.httpServer.started.is_set():
            print 'Waiting for httpserver to start...'
            self.httpServer.started.wait()

        if self.httpServer.failed is not None:
            raise self.httpServer.failed

        print "Running on port: {}".format(self.httpServer.port)

        priority = self.config["priority"]
        if not str(priority).isdigit() or priority < 100:
            priority = 0

        self.mdns.register('registration_' + str(HOST),
                           '_nmos-registration._tcp', DNS_SD_PORT,
                           {"pri": priority,
                            "api_ver": "v1.0,v1.1,v1.2",
                            "api_proto": "http"})

    def run(self):
        self.running = True
        self.start()
        while self.running:
            time.sleep(1)
        self._cleanup()

    def _cleanup(self):
        self.mdns.stop()
        self.mdns.close()
        self.httpServer.stop()
        print "Stopped main()"

    def stop(self):
        self.running = False

    def sig_handler(self):
        print 'Pressed ctrl+c'
        self.stop()