class mDNSBridgeService(object):
    def __init__(self, domain=None):
        self.running = False
        self.registered = False
        self.facade = Facade("{}/{}".format(APINAME, APIVERSION))
        self.domain = domain

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

        self.mdns_bridge = mDNSBridge(domain=self.domain)
        self.http_server = HttpServer(mDNSBridgeAPI, PORT, HOST, api_args=[self.mdns_bridge])
        self.http_server.start()
        while not self.http_server.started.is_set():
            print "Waiting for httpserver to start..."
            self.http_server.started.wait()

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

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

    def run(self):
        self.running = True
        self.start()
        self.facade.register_service("http://" + HOST + ":" + str(PORT), "{}/{}/{}/".format(APINAMESPACE, APINAME, APIVERSION))
        daemon.notify("READY=1")
        itercount = 0
        while self.running:
            itercount += 1
            gevent.sleep(1)
            if itercount == 5: #5 seconds
                self.facade.heartbeat_service()
                itercount = 0
        self.facade.unregister_service()
        self._cleanup()

    def stop(self):
        self.running = False

    def _cleanup(self):
        self.http_server.stop()
        self.mdns_bridge.stop()
        print "Stopped main()"

    def sig_handler(self):
        print "Pressed ctrl+c"
        self.stop()
class NmosDriver:
    def __init__(self, manager, logger, facade):
        # Start the web server used to show the interface
        self.logger = logger
        self.facade = facade
        self.httpServer = HttpServer(NmosDriverWebApi,
                                     WS_PORT,
                                     '0.0.0.0',
                                     api_args=[logger, manager, facade])

        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(
            "Mock driver interface running on port: {}".format(
                self.httpServer.port))
Esempio n. 3
0
class ProxyListingService(object):
    def __init__(self):
        self.running = False

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

        self.http_server = HttpServer(ProxyListingAPI, PORT, HOST)
        self.http_server.start()
        while not self.http_server.started.is_set():
            print "Waiting for httpserver to start..."
            self.http_server.started.wait()

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

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

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

    def stop(self):
        if self.running:
            self.running = False
        else:
            self.http_server.stop()
            print "Stopped main()"

    def sig_handler(self, sig, frame):
        print "Pressed ctrl+c"
        self.stop()
Esempio n. 4
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))
Esempio n. 5
0
class NodeFacadeService:
    def __init__(self, interactive=False):
        self.logger = Logger("facade", None)
        if HOST == "":
            self.logger.writeFatal(
                "Unable to start facade due to lack of connectivity")
            sys.exit(1)
        self.running = False
        self.httpServer = None
        self.interface = None
        self.interactive = interactive
        self.registry = None
        self.registry_cleaner = None
        self.node_id = None
        self.mdns = MDNSEngine()
        self.mdnsname_suffix = '_' + str(HOSTNAME) + "_" + str(getpid())
        self.mappings = {
            "device": "ver_dvc",
            "flow": "ver_flw",
            "source": "ver_src",
            "sender": "ver_snd",
            "receiver": "ver_rcv",
            "self": "ver_slf"
        }
        self.mdns_updater = MDNSUpdater(self.mdns,
                                        "_nmos-node._tcp",
                                        "node" + self.mdnsname_suffix,
                                        self.mappings,
                                        PORT,
                                        self.logger,
                                        txt_recs={
                                            "api_ver": "v1.0,v1.1,v1.2",
                                            "api_proto": "http"
                                        })
        self.aggregator = Aggregator(self.logger, self.mdns_updater)

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

    def sig_hup_handler(self):
        if getLocalIP() != "":
            global HOST
            HOST = updateHost()
            self.registry.modify_node(href=self.generate_href(),
                                      host=HOST,
                                      api={
                                          "versions": NODE_APIVERSIONS,
                                          "endpoints":
                                          self.generate_endpoints()
                                      },
                                      interfaces=self.list_interfaces())

    def generate_endpoints(self):
        endpoints = []
        if HTTPS_MODE != "enabled":
            endpoints.append({
                "host": HOST,
                "port": 80,  #Everything should go via apache proxy
                "protocol": "http"
            })
        if HTTPS_MODE != "disabled":
            endpoints.append({
                "host": HOST,
                "port": 443,  #Everything should go via apache proxy
                "protocol": "https"
            })
        return endpoints

    def generate_href(self):
        if HTTPS_MODE == "enabled":
            return "https://{}/".format(HOST)
        else:
            return "http://{}/".format(HOST)

    def list_interfaces(self):
        interfaces = {}
        # Initially populate interfaces from known-good location
        net_path = "/sys/class/net/"
        if os.path.exists(net_path):
            for interface_name in os.listdir(net_path):
                if interface_name != "lo":
                    address_path = net_path + interface_name + "/address"
                    if os.path.exists(address_path):
                        address = open(address_path, "r").readline()
                        interfaces[interface_name] = {
                            "name":
                            interface_name,
                            "chassis_id":
                            None,
                            "port_id":
                            address.lower().strip("\n").replace(":", "-")
                        }

        # Attempt to source proper LLDP data for interfaces
        if os.path.exists("/usr/sbin/lldpcli"):
            try:
                chassis_data = json.loads(
                    check_output(
                        ["/usr/sbin/lldpcli", "show", "chassis", "-f",
                         "json"]))
                chassis_id = chassis_data["local-chassis"]['chassis'].values(
                )[0]["id"]["value"]
                if chassis_data["local-chassis"]['chassis'].values(
                )[0]["id"]["type"] == "mac":
                    chassis_id = chassis_id.lower().replace(":", "-")
                interface_data = json.loads(
                    check_output([
                        "/usr/sbin/lldpcli", "show", "statistics", "-f", "json"
                    ]))
                if isinstance(interface_data["lldp"]["interface"], dict):
                    for interface_name in interface_data["lldp"][
                            "interface"].keys():
                        if interface_name in interfaces:
                            # Only correct the Chassis ID. Port ID MUST be a MAC address
                            interfaces[interface_name][
                                "chassis_id"] = chassis_id
                else:
                    for interface_block in interface_data["lldp"]["interface"]:
                        interface_name = interface_block.keys()[0]
                        if interface_name in interfaces:
                            # Only correct the Chassis ID. Port ID MUST be a MAC address
                            interfaces[interface_name][
                                "chassis_id"] = chassis_id
            except Exception:
                pass

        return interfaces.values()

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

        self.mdns.start()
        self.node_id = get_node_id()
        node_version = str(ptptime.ptp_detail()[0]) + ":" + str(
            ptptime.ptp_detail()[1])
        node_data = {
            "id":
            self.node_id,
            "label":
            nmoscommonconfig.config.get('node_label', FQDN),
            "description":
            nmoscommonconfig.config.get('node_description',
                                        "Node on {}".format(FQDN)),
            "tags":
            nmoscommonconfig.config.get('node_tags', {}),
            "href":
            self.generate_href(),
            "host":
            HOST,
            "services": [],
            "hostname":
            HOSTNAME,
            "caps": {},
            "version":
            node_version,
            "api": {
                "versions": NODE_APIVERSIONS,
                "endpoints": self.generate_endpoints(),
            },
            "clocks": [
                {
                    "name": "clk0",
                    "ref_type": "internal",
                },
                {
                    "name": "clk1",
                    "ref_type": "ptp",
                    "version": "IEEE1588-2008",
                    "traceable": False,
                    "gmid": "00-00-00-00-00-00-00-00",
                    "locked": False,
                },
                # Extra values will be filled in as needed at point of checking
            ],
            "interfaces":
            self.list_interfaces()
        }
        self.registry = FacadeRegistry(self.mappings.keys(), self.aggregator,
                                       self.mdns_updater, self.node_id,
                                       node_data, self.logger)
        self.registry_cleaner = FacadeRegistryCleaner(self.registry)
        self.registry_cleaner.start()
        self.httpServer = HttpServer(FacadeAPI,
                                     PORT,
                                     '0.0.0.0',
                                     api_args=[self.registry])
        self.httpServer.start()
        while not self.httpServer.started.is_set():
            self.logger.writeInfo('Waiting for httpserver to start...')
            self.httpServer.started.wait()

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

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

        try:
            self.logger.writeInfo("Registering as {}...".format(self.node_id))
            self.aggregator.register(
                'node', self.node_id,
                **legalise_resource(node_data, "node", NODE_REGVERSION))
        except Exception as e:
            self.logger.writeWarning("Could not register: {}".format(
                e.__repr__()))

        self.interface = FacadeInterface(self.registry, self.logger)
        self.interface.start()

    def run(self):
        self.running = True
        pidfile = "/tmp/ips-nodefacade.pid"
        file(pidfile, 'w').write(str(getpid()))
        self.start()
        daemon.notify("READY=1")
        while self.running:
            self.registry.update_ptp()
            time.sleep(1)
        os.unlink(pidfile)
        self._cleanup()

    def _cleanup(self):
        try:
            self.logger.writeDebug("cleanup: unregister facade " +
                                   self.node_id)
            self.aggregator.unregister('node', self.node_id)
        except Exception as e:
            self.logger.writeWarning("Could not unregister: {}".format(e))

        if self.mdns:
            try:
                self.mdns.stop()
            except Exception as e:
                self.logger.writeWarning("Could not stop mdns: {}".format(e))

        self.registry_cleaner.stop()
        self.interface.stop()
        self.httpServer.stop()
        self.aggregator.stop()
        self.logger.writeInfo("Stopped main()")

    def stop(self):
        self.running = False
Esempio n. 6
0
class GroupingService:
    def __init__(self, interactive=False):
        self.facades = {}
        for version in APIVERSIONS:
            self.facades[version] = Facade("{}/{}".format(APINAME, version))
        self.logger = Logger("grouping", None)
        self.running = False
        self.httpServer = None
        with open(CONFIG_PATH) as config_fp:
            self.config = json.load(config_fp)

    def _sig_handler(self):
        self.logger.writeInfo("Stopping...")
        self._stop()

    def _start(self):
        gevent.signal(signal.SIGINT, self._sig_handler)
        gevent.signal(signal.SIGTERM, self._sig_handler)

        self.httpServer = HttpServer(GroupingAPI,
                                     PORT,
                                     '0.0.0.0',
                                     ssl=self.config.get("ssl"))
        self.httpServer.start()
        while not self.httpServer.started.is_set():
            self.logger.writeInfo('Waiting for httpserver to start...')
            self.httpServer.started.wait()

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

        self.httpServer.api.app.config.update(self.config)
        db_mongo.init_app(self.httpServer.api.app, logger=self.logger)
        self.logger.writeInfo("Running on port: {}".format(
            self.httpServer.port))

    def run(self):
        self.running = True
        self._start()
        for version in APIVERSIONS:
            self.facades[version].register_service(
                "http://127.0.0.1:" + str(PORT),
                "{}/{}/{}/".format(APINAMESPACE, APINAME, version))
        itercount = 0
        while self.running:
            if itercount % 5 == 0:
                for facade in self.facades:
                    self.facades[facade].heartbeat_service()
            gevent.sleep(1)
            itercount += 1
            if itercount == 10:
                itercount = 0
        for facade in self.facades:
            self.facades[facade].unregister_service()
        self._cleanup()

    def _cleanup(self):
        self.httpServer.stop()
        self.logger.writeInfo("Stopped")

    def _stop(self):
        self.running = False
Esempio n. 7
0
class ConnectionManagementService:

    def __init__(self, logger=None):
        self.running = False
        from nmoscommon.logger import Logger
        from nmosnode.facade import Facade
        self.logger = Logger("conmanage")
        self.logger.writeWarning("Could not find ipppython facade")
        self.facade = Facade("{}/{}".format(CONN_APINAME, CONN_APIVERSIONS[-1]),
                             address="ipc:///tmp/ips-nodefacade", logger=self.logger)
        self.logger.writeDebug("Running Connection Management Service")
        self.httpServer = HttpServer(ConnectionManagementAPI, WS_PORT,
                                     '0.0.0.0', api_args=[self.logger])

    def start(self):
        '''Call this to run the API without blocking'''
        if self.running:
            gevent.signal_handler(signal.SIGINT, self.sig_handler)
            gevent.signal_handler(signal.SIGTERM, self.sig_handler)

        self.running = True

        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))

        self.facade.register_service("http://127.0.0.1:{}".format(self.httpServer.port),
                                     "{}{}/".format(CONN_ROOT[1:], CONN_APIVERSIONS[-1]))
        try:
            from nmosconnectiondriver.httpIpstudioDriver import httpIpstudioDriver
            self.logger.writeInfo("Using ipstudio driver")
            # Start the IPStudio driver
            self.driver = httpIpstudioDriver(
                self.httpServer.api,
                self.logger,
                self.facade
            )
        except ImportError:
            # Start the mock driver
            self.driver = NmosDriver(
                self.httpServer.api,
                self.logger,
                self.facade
            )

    def run(self):
        '''Call this to run the API in keep-alive (blocking) mode'''
        self.running = True
        self.start()
        itercount = 0
        while self.running:
            gevent.sleep(1)
            itercount += 1
            if itercount == 5:
                self.facade.heartbeat_service()
                itercount = 0
        self._cleanup()

    def _cleanup(self):
        self.httpServer.stop()
        self.facade.unregister_service()

    def sig_handler(self):
        self.stop()

    def stop(self):
        '''Gracefully shut down the API'''
        self._cleanup()
        self.running = False
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))
Esempio n. 9
0
class NodeFacadeService:
    def __init__(self, interactive=False):
        self.logger = Logger("facade", None)
        if HOST == "":
            self.logger.writeFatal(
                "Unable to start facade due to lack of connectivity")
            sys.exit(1)
        self.running = False
        self.httpServer = None
        self.interface = None
        self.interactive = interactive
        self.registry = None
        self.registry_cleaner = None
        self.node_id = None
        self.mdns = MDNSEngine()
        self.mappings = {
            "device": "ver_dvc",
            "flow": "ver_flw",
            "source": "ver_src",
            "sender": "ver_snd",
            "receiver": "ver_rcv",
            "self": "ver_slf"
        }
        self.mdns_updater = None
        self.auth_registry = AuthRegistry(app=None, scope=ALLOWED_SCOPE)

        self.protocol = PROTOCOL
        if PROTOCOL == "https":
            self.dns_sd_port = DNS_SD_HTTPS_PORT
        else:
            self.dns_sd_port = DNS_SD_HTTP_PORT
        if ENABLE_P2P:
            self.mdns_updater = MDNSUpdater(self.mdns,
                                            DNS_SD_TYPE,
                                            DNS_SD_NAME,
                                            self.mappings,
                                            self.dns_sd_port,
                                            self.logger,
                                            txt_recs=self._mdns_txt(
                                                NODE_APIVERSIONS,
                                                self.protocol, OAUTH_MODE))

        self.aggregator = Aggregator(self.logger, self.mdns_updater,
                                     self.auth_registry)

    def _mdns_txt(self, versions, protocol, oauth_mode):
        return {
            "api_ver": ",".join(versions),
            "api_proto": protocol,
            "api_auth": str(oauth_mode).lower()
        }

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

    def sig_hup_handler(self):
        if getLocalIP() != "":
            global HOST
            HOST = updateHost()
            self.registry.modify_node(href=self.generate_href(),
                                      host=HOST,
                                      api={
                                          "versions": NODE_APIVERSIONS,
                                          "endpoints":
                                          self.generate_endpoints()
                                      },
                                      interfaces=self.list_interfaces())

    def generate_endpoints(self):
        endpoints = []
        endpoints.append({
            "host": HOST,
            "port": self.dns_sd_port,  # Everything should go via apache proxy
            "protocol": self.protocol,
            "authorization": OAUTH_MODE
        })
        return endpoints

    def generate_href(self):
        return "{}://{}/".format(PROTOCOL, HOST)

    def list_interfaces(self):
        interfaces = {}
        # Initially populate interfaces from known-good location
        net_path = "/sys/class/net/"
        if os.path.exists(net_path):
            for interface_name in os.listdir(net_path):
                address_path = net_path + interface_name + "/address"
                if os.path.exists(address_path) and interface_name != 'lo':
                    with open(address_path, 'r') as address_file:
                        address = address_file.readline().strip('\n')
                        if address:
                            interfaces[interface_name] = {
                                "name": interface_name,
                                "chassis_id": None,
                                "port_id": address.lower().replace(":", "-")
                            }

        # Attempt to source proper LLDP data for interfaces
        if os.path.exists("/usr/sbin/lldpcli"):
            try:
                chassis_data = json.loads(
                    check_output(
                        ["/usr/sbin/lldpcli", "show", "chassis", "-f",
                         "json"]))
                chassis_id = chassis_data["local-chassis"]['chassis'].values(
                )[0]["id"]["value"]
                if chassis_data["local-chassis"]['chassis'].values(
                )[0]["id"]["type"] == "mac":
                    chassis_id = chassis_id.lower().replace(":", "-")
                interface_data = json.loads(
                    check_output([
                        "/usr/sbin/lldpcli", "show", "statistics", "-f", "json"
                    ]))
                if isinstance(interface_data["lldp"]["interface"], dict):
                    for interface_name in interface_data["lldp"][
                            "interface"].keys():
                        if interface_name in interfaces:
                            # Only correct the Chassis ID. Port ID MUST be a MAC address
                            interfaces[interface_name][
                                "chassis_id"] = chassis_id
                else:
                    for interface_block in interface_data["lldp"]["interface"]:
                        interface_name = interface_block.keys()[0]
                        if interface_name in interfaces:
                            # Only correct the Chassis ID. Port ID MUST be a MAC address
                            interfaces[interface_name][
                                "chassis_id"] = chassis_id
            except Exception:
                pass

        return list(itervalues(interfaces))

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

        self.mdns.start()
        self.node_id = get_node_id()
        node_version = str(ptptime.ptp_detail()[0]) + ":" + str(
            ptptime.ptp_detail()[1])
        node_data = {
            "id":
            self.node_id,
            "label":
            _config.get('node_label', FQDN),
            "description":
            _config.get('node_description', "Node on {}".format(FQDN)),
            "tags":
            _config.get('node_tags', {}),
            "href":
            self.generate_href(),
            "host":
            HOST,
            "services": [],
            "hostname":
            HOSTNAME,
            "caps": {},
            "version":
            node_version,
            "api": {
                "versions": NODE_APIVERSIONS,
                "endpoints": self.generate_endpoints(),
            },
            "clocks": [],
            "interfaces":
            self.list_interfaces()
        }
        self.registry = FacadeRegistry(self.mappings.keys(), self.aggregator,
                                       self.mdns_updater, self.node_id,
                                       node_data, self.logger)
        self.registry_cleaner = FacadeRegistryCleaner(self.registry)
        self.registry_cleaner.start()
        self.httpServer = HttpServer(
            FacadeAPI,
            PORT,
            '0.0.0.0',
            api_args=[self.registry, self.auth_registry])
        self.httpServer.start()
        while not self.httpServer.started.is_set():
            self.logger.writeInfo('Waiting for httpserver to start...')
            self.httpServer.started.wait()

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

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

        try:
            self.logger.writeInfo("Registering as {}...".format(self.node_id))
            self.aggregator.register(
                'node', self.node_id,
                **translate_api_version(node_data, "node", NODE_REGVERSION))
        except Exception as e:
            self.logger.writeWarning("Could not register: {}".format(
                e.__repr__()))

        self.interface = FacadeInterface(self.registry, self.logger)
        self.interface.start()

    def run(self):
        self.running = True
        pidfile = "/tmp/ips-nodefacade.pid"
        with open(pidfile, 'w') as f:
            f.write(str(getpid()))
        self.start()
        daemon.notify(SYSTEMD_READY)
        while self.running:
            self.registry.update_ptp()
            time.sleep(1)
        os.unlink(pidfile)

    def _cleanup(self):
        try:
            self.logger.writeDebug("cleanup: unregister facade " +
                                   self.node_id)
            self.aggregator.unregister('node', self.node_id)
        except Exception as e:
            self.logger.writeWarning("Could not unregister: {}".format(e))

        if self.mdns:
            try:
                self.mdns.stop()
            except Exception as e:
                self.logger.writeWarning("Could not stop mdns: {}".format(e))

        self.registry_cleaner.stop()
        self.interface.stop()
        self.httpServer.stop()
        self.aggregator.stop()
        self.mdns_updater.stop()
        self.logger.writeInfo("Stopped main()")

    def stop(self):
        self._cleanup()
        self.running = False
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()