Example #1
0
 def __init__(self):
     self._database = DatabaseConnection()
     self.node = ThorEntity(host.default_ip if ServerConfig.address
                            == '0.0.0.0' else ServerConfig.address,
                            ['xcap_server'],
                            version=xcap.__version__)
     self.networks = {}
     self.presence_message = ThorEvent('Thor.Presence', self.node.id)
     self.shutdown_message = ThorEvent('Thor.Leave', self.node.id)
     credentials = X509Credentials(ThorNodeConfig.certificate,
                                   ThorNodeConfig.private_key,
                                   [ThorNodeConfig.ca])
     credentials.verify_peer = True
     tls_context = TLSContext(credentials)
     self.control = ControlLink(tls_context)
     EventServiceClient.__init__(self, ThorNodeConfig.domain, tls_context)
     process.signals.add_handler(signal.SIGHUP, self._handle_SIGHUP)
     process.signals.add_handler(signal.SIGINT, self._handle_SIGINT)
     process.signals.add_handler(signal.SIGTERM, self._handle_SIGTERM)
Example #2
0
 def __init__(self):
     self._database = DatabaseConnection()
     self.node = ThorEntity(host.default_ip if ServerConfig.address == '0.0.0.0' else ServerConfig.address, ['xcap_server'], version=xcap.__version__)
     self.networks = {}
     self.presence_message = ThorEvent('Thor.Presence', self.node.id)
     self.shutdown_message = ThorEvent('Thor.Leave', self.node.id)
     credentials = X509Credentials(ThorNodeConfig.certificate, ThorNodeConfig.private_key, [ThorNodeConfig.ca])
     credentials.verify_peer = True
     credentials.session_params.compressions = (COMP_LZO, COMP_DEFLATE, COMP_NULL)
     self.control = ControlLink(credentials)
     EventServiceClient.__init__(self, ThorNodeConfig.domain, credentials)
     process.signals.add_handler(signal.SIGHUP, self._handle_SIGHUP)
     process.signals.add_handler(signal.SIGINT, self._handle_SIGINT)
     process.signals.add_handler(signal.SIGTERM, self._handle_SIGTERM)
Example #3
0
class XCAPProvisioning(EventServiceClient):
    __metaclass__ = Singleton
    topics = ["Thor.Members"]

    def __init__(self):
        self._database = DatabaseConnection()
        self.node = ThorEntity(host.default_ip if ServerConfig.address == '0.0.0.0' else ServerConfig.address, ['xcap_server'], version=xcap.__version__)
        self.networks = {}
        self.presence_message = ThorEvent('Thor.Presence', self.node.id)
        self.shutdown_message = ThorEvent('Thor.Leave', self.node.id)
        credentials = X509Credentials(ThorNodeConfig.certificate, ThorNodeConfig.private_key, [ThorNodeConfig.ca])
        credentials.verify_peer = True
        credentials.session_params.compressions = (COMP_LZO, COMP_DEFLATE, COMP_NULL)
        self.control = ControlLink(credentials)
        EventServiceClient.__init__(self, ThorNodeConfig.domain, credentials)
        process.signals.add_handler(signal.SIGHUP, self._handle_SIGHUP)
        process.signals.add_handler(signal.SIGINT, self._handle_SIGINT)
        process.signals.add_handler(signal.SIGTERM, self._handle_SIGTERM)

    def _disconnect_all(self, result):
        self.control.disconnect_all()
        EventServiceClient._disconnect_all(self, result)

    def lookup(self, key):
        network = self.networks.get("sip_proxy", None)
        if network is None:
            return None
        try:
            node = network.lookup_node(key)
        except LookupError:
            node = None
        except Exception:
            log.err()
            node = None
        return node

    def notify(self, operation, entity_type, entity):
        node = self.lookup(entity)
        if node is not None:
            if node.control_port is None:
                log.error("Could not send notify because node %s has no control port" % node.ip)
                return
            self.control.send_request(Notification("notify %s %s %s" % (operation, entity_type, entity)), (node.ip, node.control_port))

    def get_watchers(self, key):
        node = self.lookup(key)
        if node is None:
            return defer.fail("no nodes found when searching for key %s" % str(key))
        if node.control_port is None:
            return defer.fail("could not send notify because node %s has no control port" % node.ip)
        request = GetSIPWatchers(key)
        request.deferred = Deferred()
        self.control.send_request(request, (node.ip, node.control_port))
        return request.deferred

    def handle_event(self, event):
        # print "Received event: %s" % event
        networks = self.networks
        role_map = ThorEntitiesRoleMap(event.message) ## mapping between role names and lists of nodes with that role
        thor_databases = role_map.get('thor_database', [])
        if thor_databases:
            thor_databases.sort(lambda x, y: cmp(x.priority, y.priority) or cmp(x.ip, y.ip))
            dburi = thor_databases[0].dburi
        else:
            dburi = None
        self._database.update_dburi(dburi)
        all_roles = role_map.keys() + networks.keys()
        for role in all_roles:
            try:
                network = networks[role] ## avoid setdefault here because it always evaluates the 2nd argument
            except KeyError:
                from thor import network as thor_network
                if role in ["thor_manager", "thor_monitor", "provisioning_server", "media_relay", "thor_database"]:
                    continue
                else:
                    network = thor_network.new(ThorNodeConfig.multiply)
                networks[role] = network
            new_nodes = set([ThorEntityAddress(node.ip, getattr(node, 'control_port', None), getattr(node, 'version', 'unknown')) for node in role_map.get(role, [])])
            old_nodes = set(network.nodes)
            ## compute set differences
            added_nodes = new_nodes - old_nodes
            removed_nodes = old_nodes - new_nodes
            if removed_nodes:
                for node in removed_nodes:
                    network.remove_node(node)
                    self.control.discard_link((node.ip, node.control_port))
                plural = len(removed_nodes) != 1 and 's' or ''
                log.msg("removed %s node%s: %s" % (role, plural, ', '.join(removed_nodes)))
            if added_nodes:
                for node in added_nodes:
                    network.add_node(node)
                plural = len(added_nodes) != 1 and 's' or ''
                log.msg("added %s node%s: %s" % (role, plural, ', '.join(added_nodes)))
Example #4
0
class XCAPProvisioning(EventServiceClient):
    __metaclass__ = Singleton
    topics = ["Thor.Members"]

    def __init__(self):
        self._database = DatabaseConnection()
        self.node = ThorEntity(host.default_ip if ServerConfig.address
                               == '0.0.0.0' else ServerConfig.address,
                               ['xcap_server'],
                               version=xcap.__version__)
        self.networks = {}
        self.presence_message = ThorEvent('Thor.Presence', self.node.id)
        self.shutdown_message = ThorEvent('Thor.Leave', self.node.id)
        credentials = X509Credentials(ThorNodeConfig.certificate,
                                      ThorNodeConfig.private_key,
                                      [ThorNodeConfig.ca])
        credentials.verify_peer = True
        tls_context = TLSContext(credentials)
        self.control = ControlLink(tls_context)
        EventServiceClient.__init__(self, ThorNodeConfig.domain, tls_context)
        process.signals.add_handler(signal.SIGHUP, self._handle_SIGHUP)
        process.signals.add_handler(signal.SIGINT, self._handle_SIGINT)
        process.signals.add_handler(signal.SIGTERM, self._handle_SIGTERM)

    def _disconnect_all(self, result):
        self.control.disconnect_all()
        EventServiceClient._disconnect_all(self, result)

    def lookup(self, key):
        network = self.networks.get("sip_proxy", None)
        if network is None:
            return None
        try:
            node = network.lookup_node(key)
        except LookupError:
            node = None
        except Exception:
            log.exception()
            node = None
        return node

    def notify(self, operation, entity_type, entity):
        node = self.lookup(entity)
        if node is not None:
            if node.control_port is None:
                log.error(
                    "Could not send notify because node %s has no control port"
                    % node.ip)
                return
            self.control.send_request(
                Notification("notify %s %s %s" %
                             (operation, entity_type, entity)),
                (node.ip, node.control_port))

    def get_watchers(self, key):
        node = self.lookup(key)
        if node is None:
            return defer.fail("no nodes found when searching for key %s" %
                              str(key))
        if node.control_port is None:
            return defer.fail(
                "could not send notify because node %s has no control port" %
                node.ip)
        request = GetSIPWatchers(key)
        request.deferred = Deferred()
        self.control.send_request(request, (node.ip, node.control_port))
        return request.deferred

    def handle_event(self, event):
        # print "Received event: %s" % event
        networks = self.networks
        role_map = ThorEntitiesRoleMap(
            event.message
        )  ## mapping between role names and lists of nodes with that role
        thor_databases = role_map.get('thor_database', [])
        if thor_databases:
            thor_databases.sort(
                lambda x, y: cmp(x.priority, y.priority) or cmp(x.ip, y.ip))
            dburi = thor_databases[0].dburi
        else:
            dburi = None
        self._database.update_dburi(dburi)
        all_roles = role_map.keys() + networks.keys()
        for role in all_roles:
            try:
                network = networks[
                    role]  ## avoid setdefault here because it always evaluates the 2nd argument
            except KeyError:
                from thor import network as thor_network
                if role in [
                        "thor_manager", "thor_monitor", "provisioning_server",
                        "media_relay", "thor_database"
                ]:
                    continue
                else:
                    network = thor_network.new(ThorNodeConfig.multiply)
                networks[role] = network
            new_nodes = set([
                ThorEntityAddress(node.ip, getattr(node, 'control_port', None),
                                  getattr(node, 'version', 'unknown'))
                for node in role_map.get(role, [])
            ])
            old_nodes = set(network.nodes)
            added_nodes = new_nodes - old_nodes
            removed_nodes = old_nodes - new_nodes
            if removed_nodes:
                for node in removed_nodes:
                    network.remove_node(node)
                    self.control.discard_link((node.ip, node.control_port))
                log.info('Removed %s nodes: %s' %
                         (role, ', '.join(removed_nodes)))
            if added_nodes:
                for node in added_nodes:
                    network.add_node(node)
                log.info('Added %s nodes: %s' % (role, ', '.join(added_nodes)))