예제 #1
0
    def start(self, thread_init_callback):
        assert not self._started
        self._started = True
        for i in range(self._num_thread):
            thr = ZEventLoopThread(thread_init_callback)
            self._loop_threads.append(thr)
            self._event_loops.append(thr.start_loop())

        if self._num_thread == 0 and thread_init_callback:
            thread_init_callback(self._base_loop)
예제 #2
0
 def __init__(self, server_addr):
     self._event_loop_thread = ZEventLoopThread()
     self._tcp_client = ZTcpClient(self._event_loop_thread.start_loop(), server_addr)
     self._codec = ZLengthHeadCodec(self._on_string_message)
     self._tcp_client.set_connection_callback(self._on_connection)
     self._tcp_client.set_message_callback(self._codec.on_message)
     self._tcp_conn = None
     self._guard = Condition(Lock())
예제 #3
0
 def __init__(self, cfg_parser):
     self._cfg_parser = cfg_parser
     self._db_conn = self._create_db_conn()
     self._db_cursor = self._db_conn.cursor()
     self._event_loop_thread = ZEventLoopThread() 
     self._event_loop = self._event_loop_thread.start_loop()
     self._guard = Condition(Lock())
     self._scan_servers = self._get_scan_servers()
     self._scanner_clients = {}
예제 #4
0
class TestTcpClient(object):
    def __init__(self, server_addr):
        self._event_loop_thread = ZEventLoopThread()
        self._tcp_client = ZTcpClient(self._event_loop_thread.start_loop(), server_addr)
        self._codec = ZLengthHeadCodec(self._on_string_message)
        self._tcp_client.set_connection_callback(self._on_connection)
        self._tcp_client.set_message_callback(self._codec.on_message)
        self._tcp_conn = None
        self._guard = Condition(Lock())

    def connect(self):
        self._tcp_client.connect()

    def send_message_until_quit(self):
        while True:
            try:
                s = input()
                if s.find("bye") < 0:
                    self._write(s)
                else:
                    self._tcp_client.disconnect()
                    return
            except Exception as e:
                logging.error("input error %s" % (str(e)))

    def _write(self, s):
        with self._guard:
            if self._tcp_conn is not None:
                self._codec.send(self._tcp_conn, s)

    def _on_connection(self, tcp_conn):
        logging.info(tcp_conn.name() + " is " + (tcp_conn.connected() and "UP" or "DOWN"))
        with self._guard:
            if tcp_conn.connected():
                self._tcp_conn = tcp_conn
            else:
                self._tcp_conn = None

    def _on_string_message(self, tcp_conn, message, recieve_time):
        logging.info(message)
예제 #5
0
class ScannerClient(object):
    PORT = 9876
    def __init__(self, cfg_parser):
        self._cfg_parser = cfg_parser
        self._db_conn = self._create_db_conn()
        self._db_cursor = self._db_conn.cursor()
        self._event_loop_thread = ZEventLoopThread() 
        self._event_loop = self._event_loop_thread.start_loop()
        self._guard = Condition(Lock())
        self._scan_servers = self._get_scan_servers()
        self._scanner_clients = {}

    def start(self, scan_filters):
        jobs = self._get_jobs(scan_filters)
        self._scanner_clients.clear()
        for sid, job in enumerate(jobs):
            logging.info('handling job (%s, %s) ' %(job[0], job[1]))
            scanner_client = Scanner(self._event_loop, sid, (job[0], self.PORT))
            scanner_client.set_connection_callback(self._on_connection)
            scanner_client.set_connection_error_callback(self._on_error_connection)
            scanner_client.set_message_callback(self._on_message)
            scanner_client.connect()
            with self._guard:
                self._scanner_clients[sid] = [scanner_client, job]

    def _on_connection(self, scanner_client, tcp_conn):
        if tcp_conn.connected():
            with self._guard:
                job = self._scanner_clients[scanner_client.get_id()][1]
                scan_list = job[1]
    
            job_elem = ElementTree.Element('job', {'name':'scan'})
            job_elem.text = '\n%s\n' % scan_list
            job_xml = '<?xml version="1.0"?>\n%s' % ElementTree.tostring(job_elem)
            scanner_client.send(tcp_conn, job_xml)
        else:
            with self._guard:
                self._scanner_clients.pop(scanner_client.get_id())
    
    def _on_message(self, scanner_client, tcp_conn, message, receive_time):
        with self._guard:
            job = self._scanner_clients[scanner_client.get_id()][1]
            logging.info('receive message %s for job %s' %(message, job[0]))
            scanner_client.disconnect()

    def _on_error_connection(self, server_addr, errno):
        logging.error('failed to connect to %s, errno=(%d)' %str(server_addr), errno)
        # FIXME Propergate this error to up layer

    def quit(self):
        with self._guard:
            if not self._scanner_clients:
                self._event_loop.quit()
            else:
                logging.warn('We are waiting for the reply from the scan servers')

    def _get_scan_servers(self):
        statement = 'SELECT site, ip FROM %s' %(self._cfg_parser.get('DATABASE', 'scan_server_tbl'))
        self._db_cursor.execute(statement)
        return dict(self._db_cursor.fetchall())

    def _get_jobs(self, scan_filters):
        # dispatch jobs among the scan server accoring to user's selection
        scan_info_tbl = self._cfg_parser.get('DATABASE', 'scan_info_tbl')
        jobs = []
        if not scan_filters:
            statement = "SELECT site, string_agg(scan_info, E'\n') FROM %s GROUP BY site" %(scan_info_tbl)
            self._db_cursor.execute(statement)
            for r in self._db_cursor.fetchall():
                site, scan_info = r
                if site and scan_info:
                    jobs.append((self._scan_servers[site], scan_info + '\n'))
        else:
            where_states = [] 
            for site in scan_filters:
                statement = "SELECT site, scan_info FROM %s " %(scan_info_tbl)
                del where_states[:]
                if not scan_filters[site]:
                    where_states.append("(site = '%s')" %(site))
                else:
                    for file_server in scan_filters[site]:
                        if not scan_filters[site][file_server]:
                            where_states.append("(site = '%s' and file_server = '%s')" %(site, file_server))
                        else:
                            for export_root in scan_filters[site][file_server]:
                                where_states.append("(site = '%s' and file_server = '%s' and export_root = '%s')" 
                                                    %(site, file_server, export_root))
                statement = '%s WHERE %s' %(statement, ' or '.join(where_states))
                logging.info('execute query %s' %(statement))
                self._db_cursor.execute(statement)
                scan_list = '\n'.join([r[1] for r in self._db_cursor.fetchall() if r[1]])
                if scan_list:
                    jobs.append((self._scan_servers[site], scan_list))
        return jobs
    
    def _create_db_conn(self):
        db_section = 'DATABASE'
        db_conn = None
        try:
            db_conn = ZDbConn.create_db_connection(self._cfg_parser.get(db_section, 'type'),
                                                   self._cfg_parser.get(db_section, 'host'),
                                                   self._cfg_parser.get(db_section, 'user'),
                                                   self._cfg_parser.get(db_section, 'password'),
                                                   self._cfg_parser.get(db_section, 'db'))
        except Exception as e:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            logging.error('Scanner._create_db_conn encounting error %s' 
                          %(''.join(format_exception(exc_type, exc_value, exc_traceback))))
        return db_conn