Example #1
0
    def connectToClusterServer(self, useSSL, certificatePath, clusterServerIP,
                               clusterServerListenningPort,
                               statusDBUpdateInterval, commandTimeout,
                               commandTimeoutCheckInterval):
        """
        Establishes a connection with the cluster server
        Args:
            certificatePath: the directory where the server.crt and server.key files are
            clusterServerIP: the cluster server's IP address
            clusterServerListenningPort: the cluster server commands connection's port
            statusDBUpdateInterval: the database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()

        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__packetHandler = ClusterServerPacketHandler(
            self.__networkManager)
        self.__commandsProcessor = CommandsProcessor(
            self.__commandsHandler, self.__packetHandler,
            self.__networkManager, self.__clusterServerIP,
            self.__clusterServerPort, self.__commandsDBConnector,
            self.__endpointDBConnector)
        packetReactor = ClusterEndpointPacketReactor(
            self.__codeTranslator, self.__commandsHandler,
            self.__packetHandler, self.__commandsProcessor,
            self.__endpointDBConnector, self.__commandsDBConnector)
        try:
            self.__networkManager.connectTo(clusterServerIP,
                                            clusterServerListenningPort, 5,
                                            packetReactor, useSSL)
            while (not self.__networkManager.isConnectionReady(
                    clusterServerIP, clusterServerListenningPort)):
                sleep(0.1)
            self.__updateRequestThread = VMServerMonitoringThread(
                self.__packetHandler, self.__networkManager,
                self.__commandsProcessor, self.__clusterServerIP,
                self.__clusterServerPort, statusDBUpdateInterval)
            self.__updateRequestThread.start()
            self.__commandExecutionThread = CommandsMonitoringThread(
                self.__commandsDBConnector, commandTimeout,
                self.__commandsHandler, commandTimeoutCheckInterval)
            self.__commandExecutionThread.start()
        except NetworkManagerException as e:
            raise Exception(e.message)
    def connectToClusterServer(self, useSSL, certificatePath, clusterServerIP, clusterServerListenningPort, statusDBUpdateInterval,
                               commandTimeout, commandTimeoutCheckInterval):
        """
        Establishes a connection with the cluster server
        Args:
            certificatePath: the directory where the server.crt and server.key files are
            clusterServerIP: the cluster server's IP address
            clusterServerListenningPort: the cluster server commands connection's port
            statusDBUpdateInterval: the database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()

        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__packetHandler = ClusterServerPacketHandler(self.__networkManager)     
        self.__commandsProcessor = CommandsProcessor(self.__commandsHandler, self.__packetHandler, self.__networkManager, 
                 self.__clusterServerIP, self.__clusterServerPort, self.__commandsDBConnector, self.__endpointDBConnector)
        packetReactor = ClusterEndpointPacketReactor(self.__codeTranslator, self.__commandsHandler, self.__packetHandler, self.__commandsProcessor,
                                                     self.__endpointDBConnector, self.__commandsDBConnector)
        try :
            self.__networkManager.connectTo(clusterServerIP, clusterServerListenningPort, 5, packetReactor, useSSL)
            while (not self.__networkManager.isConnectionReady(clusterServerIP, clusterServerListenningPort)) :
                sleep(0.1)                   
            self.__updateRequestThread = VMServerMonitoringThread(self.__packetHandler, self.__networkManager, self.__commandsProcessor, 
                                                                  self.__clusterServerIP, self.__clusterServerPort, statusDBUpdateInterval)
            self.__updateRequestThread.start()            
            self.__commandExecutionThread = CommandsMonitoringThread(self.__commandsDBConnector, commandTimeout, self.__commandsHandler, commandTimeoutCheckInterval)
            self.__commandExecutionThread.start()
        except NetworkManagerException as e :
            raise Exception(e.message)
 def startListenning(self, useSSL, certificatePath, listenningPort, repositoryIP, repositoryPort, vmServerStatusUpdateInterval):
     """
     Creates the control connection
     Args:
         useSSL: indicates if SSL encryption must be used in the control connection or not
         certificatePath: the directory where the server.crt and server.key files are
         listenningPort: the control connection's port
         repositoryIP: the image repository IP address
         repositoryPort: the image repository's port
         vmServerStatusUpdateInterval: the virtual machine server status database interval
     Returns:
         Nothing
     """            
     
     self.__networkManager = NetworkManager(certificatePath)        
     self.__networkManager.startNetworkService()    
     self.__listenningPort = listenningPort
     self.__packetHandler = ClusterServerPacketHandler(self.__networkManager)    
     self.__useSSL = useSSL
     imageRepositoryPacketHandler = ImageRepositoryPacketHandler(self.__networkManager)
     vmServerPacketHandler = VMServerPacketHandler(self.__networkManager)        
     networkEventsReactor = NetworkEventsReactor(self.__dbConnector, repositoryIP, repositoryPort)
     
     
     imageRepositoryPacketReactor = ImageRepositoryPacketReactor(self.__dbConnector, self.__networkManager,
                                                                 listenningPort, repositoryIP, repositoryPort,
                                                                 self.__packetHandler, vmServerPacketHandler, imageRepositoryPacketHandler)
     try :
         imageRepositoryCallback = ImageRepositoryCallback(imageRepositoryPacketReactor, networkEventsReactor)
         self.__networkManager.connectTo(repositoryIP, repositoryPort, 10, imageRepositoryCallback, self.__useSSL, True)
         self.__dbConnector.addImageRepository(repositoryIP, repositoryPort, SERVER_STATE_T.READY) 
     except Exception as e:
         print "Can't connect to the image repository: " + e.message
         self.__exit = True
         return        
     
     vmServerPacketReactor = VMServerPacketReactor(self.__dbConnector, self.__networkManager, listenningPort,
                                                   vmServerPacketHandler, self.__packetHandler)
     
     self.__endpointPacketReactor = EndpointPacketReactor(self.__dbConnector, self.__networkManager, 
                                                          vmServerPacketHandler, self.__packetHandler,
                                                          imageRepositoryPacketHandler,
                                                          VMServerCallback(vmServerPacketReactor, networkEventsReactor),
                                                          listenningPort, repositoryIP, repositoryPort, self.__loadBalancerSettings,
                                                          self.__averageCompressionRatio, self.__useSSL) 
     clusterEndpointCallback = ClusterEndpointCallback(self.__endpointPacketReactor)
     self.__networkManager.listenIn(listenningPort, clusterEndpointCallback, self.__useSSL)
    
     self.__statusMonitoringThread = ClusterStatusMonitoringThread(vmServerStatusUpdateInterval,
                                                                   self.__dbConnector, self.__networkManager,
                                                                   repositoryIP, repositoryPort,
                                                                   vmServerPacketHandler, imageRepositoryPacketHandler)
     self.__statusMonitoringThread.start()           
Example #4
0
class ClusterEndpointEntryPoint(object):
    """
    These objects create, run and stop the cluster endpoint daemons.
    """
    def __init__(self):
        """
        Initializes the daemon's state
        Args:
            None
        """
        self.__commandExecutionThread = None
        self.__updateRequestThread = None
        self.__codeTranslator = SpanishCodesTranslator()
        self.__commandsHandler = CommandsHandler(self.__codeTranslator)

    def connectToDatabases(self, mysqlRootsPassword, endpointDBName,
                           commandsDBName, endpointdbSQLFilePath,
                           commandsDBSQLFilePath, websiteUser,
                           websiteUserPassword, endpointUser,
                           endpointUserPassword, minCommandInterval):
        """
        Establishes the connection with the two databases
        Args:
            mysqlRootsPassword: the MySQL root's password
            endpointDBName: the endpoint database's name
            endpointdbSQLFilePath: the endpoint database's schema definition file path
            websiteUser: the web application's username
            websiteUserPassword: the web application's username
            endpointUser: the endpoint daemon user's name
            endpointUserPassword: the endpoint daemon user's password
        """
        self.__rootsPassword = mysqlRootsPassword
        self.__statusDatabaseName = endpointDBName
        self.__commandsDatabaseName = commandsDBName
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(endpointDBName, endpointdbSQLFilePath,
                                  "root", mysqlRootsPassword)
        configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath,
                                  "root", mysqlRootsPassword)

        configurator.addUser(websiteUser, websiteUserPassword, endpointDBName,
                             False)
        configurator.addUser(endpointUser, endpointUserPassword,
                             endpointDBName, True)
        configurator.addUser(websiteUser, websiteUserPassword, commandsDBName,
                             True)
        configurator.addUser(endpointUser, endpointUserPassword,
                             commandsDBName, True)

        self.__commandsDBConnector = CommandsDatabaseConnector(
            endpointUser, endpointUserPassword, commandsDBName,
            minCommandInterval)
        self.__endpointDBConnector = ClusterEndpointDBConnector(
            endpointUser, endpointUserPassword, endpointDBName)

    def connectToClusterServer(self, useSSL, certificatePath, clusterServerIP,
                               clusterServerListenningPort,
                               statusDBUpdateInterval, commandTimeout,
                               commandTimeoutCheckInterval):
        """
        Establishes a connection with the cluster server
        Args:
            certificatePath: the directory where the server.crt and server.key files are
            clusterServerIP: the cluster server's IP address
            clusterServerListenningPort: the cluster server commands connection's port
            statusDBUpdateInterval: the database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()

        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__packetHandler = ClusterServerPacketHandler(
            self.__networkManager)
        self.__commandsProcessor = CommandsProcessor(
            self.__commandsHandler, self.__packetHandler,
            self.__networkManager, self.__clusterServerIP,
            self.__clusterServerPort, self.__commandsDBConnector,
            self.__endpointDBConnector)
        packetReactor = ClusterEndpointPacketReactor(
            self.__codeTranslator, self.__commandsHandler,
            self.__packetHandler, self.__commandsProcessor,
            self.__endpointDBConnector, self.__commandsDBConnector)
        try:
            self.__networkManager.connectTo(clusterServerIP,
                                            clusterServerListenningPort, 5,
                                            packetReactor, useSSL)
            while (not self.__networkManager.isConnectionReady(
                    clusterServerIP, clusterServerListenningPort)):
                sleep(0.1)
            self.__updateRequestThread = VMServerMonitoringThread(
                self.__packetHandler, self.__networkManager,
                self.__commandsProcessor, self.__clusterServerIP,
                self.__clusterServerPort, statusDBUpdateInterval)
            self.__updateRequestThread.start()
            self.__commandExecutionThread = CommandsMonitoringThread(
                self.__commandsDBConnector, commandTimeout,
                self.__commandsHandler, commandTimeoutCheckInterval)
            self.__commandExecutionThread.start()
        except NetworkManagerException as e:
            raise Exception(e.message)

    def doEmergencyStop(self):
        """
        Stops the endpoint daemon immediately
        Args:
            None
        Returns:
            Nothing
        """
        self.__networkManager.stopNetworkService()
        if (self.__updateRequestThread != None):
            self.__updateRequestThread.stop()
        if (self.__commandExecutionThread != None):
            self.__commandExecutionThread.stop()

    def disconnectFromClusterServer(self):
        """
        Closes the connection with the cluster server
        Args:
            None
        Devuelve:
            Nada
        """
        p = self.__packetHandler.createHaltPacket(
            self.__commandsProcessor.haltVMServers())
        errorMessage = self.__networkManager.sendPacket(
            self.__clusterServerIP, self.__clusterServerPort, p)
        NetworkManager.printConnectionWarningIfNecessary(
            self.__clusterServerIP, self.__clusterServerPort,
            "Cluster server halt", errorMessage)
        self.__updateRequestThread.stop()

        self.__commandExecutionThread.stop()

        self.closeNetworkConnections()

    def closeNetworkConnections(self):
        """
        Closes the network connections
        Args:
            None
        Returns:
            Nothing
        """
        self.__networkManager.stopNetworkService()

    def processCommands(self):
        """
        Processes the users' requests
        Args:
            None
        Returns:
            Nothing
        """
        self.__commandsProcessor.processCommands()
    def startListenning(self, useSSL, certificatePath, listenningPort,
                        repositoryIP, repositoryPort,
                        vmServerStatusUpdateInterval):
        """
        Creates the control connection
        Args:
            useSSL: indicates if SSL encryption must be used in the control connection or not
            certificatePath: the directory where the server.crt and server.key files are
            listenningPort: the control connection's port
            repositoryIP: the image repository IP address
            repositoryPort: the image repository's port
            vmServerStatusUpdateInterval: the virtual machine server status database interval
        Returns:
            Nothing
        """

        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()
        self.__listenningPort = listenningPort
        self.__packetHandler = ClusterServerPacketHandler(
            self.__networkManager)
        self.__useSSL = useSSL
        imageRepositoryPacketHandler = ImageRepositoryPacketHandler(
            self.__networkManager)
        vmServerPacketHandler = VMServerPacketHandler(self.__networkManager)
        networkEventsReactor = NetworkEventsReactor(self.__dbConnector,
                                                    repositoryIP,
                                                    repositoryPort)

        imageRepositoryPacketReactor = ImageRepositoryPacketReactor(
            self.__dbConnector, self.__networkManager, listenningPort,
            repositoryIP, repositoryPort, self.__packetHandler,
            vmServerPacketHandler, imageRepositoryPacketHandler)
        try:
            imageRepositoryCallback = ImageRepositoryCallback(
                imageRepositoryPacketReactor, networkEventsReactor)
            self.__networkManager.connectTo(repositoryIP, repositoryPort, 10,
                                            imageRepositoryCallback,
                                            self.__useSSL, True)
            self.__dbConnector.addImageRepository(repositoryIP, repositoryPort,
                                                  SERVER_STATE_T.READY)
        except Exception as e:
            print "Can't connect to the image repository: " + e.message
            self.__exit = True
            return

        vmServerPacketReactor = VMServerPacketReactor(self.__dbConnector,
                                                      self.__networkManager,
                                                      listenningPort,
                                                      vmServerPacketHandler,
                                                      self.__packetHandler)

        self.__endpointPacketReactor = EndpointPacketReactor(
            self.__dbConnector, self.__networkManager, vmServerPacketHandler,
            self.__packetHandler, imageRepositoryPacketHandler,
            VMServerCallback(vmServerPacketReactor,
                             networkEventsReactor), listenningPort,
            repositoryIP, repositoryPort, self.__loadBalancerSettings,
            self.__averageCompressionRatio, self.__useSSL)
        clusterEndpointCallback = ClusterEndpointCallback(
            self.__endpointPacketReactor)
        self.__networkManager.listenIn(listenningPort, clusterEndpointCallback,
                                       self.__useSSL)

        self.__statusMonitoringThread = ClusterStatusMonitoringThread(
            vmServerStatusUpdateInterval, self.__dbConnector,
            self.__networkManager, repositoryIP, repositoryPort,
            vmServerPacketHandler, imageRepositoryPacketHandler)
        self.__statusMonitoringThread.start()
class ClusterServerMainReactor(object):
    '''
    This class is associated with the cluster server main reactor.
    '''
    def __init__(self, loadBalancerSettings, averageCompressionRatio, timeout):
        """
        Initializes the reactor's state
        Args:
            loadBalancerSettings: a list containing the load balancing algorithm settings
            averageCompressionRation: the compression algorithm's average compression ratio
            timeout: the virtual machine boot commands timeout
        """
        self.__exit = False
        self.__loadBalancerSettings = loadBalancerSettings
        self.__averageCompressionRatio = averageCompressionRatio
        self.__timeout = timeout
        self.__statusMonitoringThread = None

    def connectToDatabase(self, mysqlRootsPassword, dbName, dbUser, dbPassword,
                          scriptPath):
        """
        Establishes a connection with the cluster server database
        Args:
            mysqlRootsPassword: the MySQL root user's password
            dbName: a database name
            dbUser: a MySQL user name
            dbPassword: the user's password
            scriptPath: the schema definition script
        Returns:
            Nothing
        """
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(dbName, scriptPath, "root",
                                  mysqlRootsPassword)
        configurator.addUser(dbUser, dbPassword, dbName, True)
        self.__dbConnector = ClusterServerDatabaseConnector(
            dbUser, dbPassword, dbName)
        self.__dbConnector.initializeVMServersStatus()

    def startListenning(self, useSSL, certificatePath, listenningPort,
                        repositoryIP, repositoryPort,
                        vmServerStatusUpdateInterval):
        """
        Creates the control connection
        Args:
            useSSL: indicates if SSL encryption must be used in the control connection or not
            certificatePath: the directory where the server.crt and server.key files are
            listenningPort: the control connection's port
            repositoryIP: the image repository IP address
            repositoryPort: the image repository's port
            vmServerStatusUpdateInterval: the virtual machine server status database interval
        Returns:
            Nothing
        """

        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()
        self.__listenningPort = listenningPort
        self.__packetHandler = ClusterServerPacketHandler(
            self.__networkManager)
        self.__useSSL = useSSL
        imageRepositoryPacketHandler = ImageRepositoryPacketHandler(
            self.__networkManager)
        vmServerPacketHandler = VMServerPacketHandler(self.__networkManager)
        networkEventsReactor = NetworkEventsReactor(self.__dbConnector,
                                                    repositoryIP,
                                                    repositoryPort)

        imageRepositoryPacketReactor = ImageRepositoryPacketReactor(
            self.__dbConnector, self.__networkManager, listenningPort,
            repositoryIP, repositoryPort, self.__packetHandler,
            vmServerPacketHandler, imageRepositoryPacketHandler)
        try:
            imageRepositoryCallback = ImageRepositoryCallback(
                imageRepositoryPacketReactor, networkEventsReactor)
            self.__networkManager.connectTo(repositoryIP, repositoryPort, 10,
                                            imageRepositoryCallback,
                                            self.__useSSL, True)
            self.__dbConnector.addImageRepository(repositoryIP, repositoryPort,
                                                  SERVER_STATE_T.READY)
        except Exception as e:
            print "Can't connect to the image repository: " + e.message
            self.__exit = True
            return

        vmServerPacketReactor = VMServerPacketReactor(self.__dbConnector,
                                                      self.__networkManager,
                                                      listenningPort,
                                                      vmServerPacketHandler,
                                                      self.__packetHandler)

        self.__endpointPacketReactor = EndpointPacketReactor(
            self.__dbConnector, self.__networkManager, vmServerPacketHandler,
            self.__packetHandler, imageRepositoryPacketHandler,
            VMServerCallback(vmServerPacketReactor,
                             networkEventsReactor), listenningPort,
            repositoryIP, repositoryPort, self.__loadBalancerSettings,
            self.__averageCompressionRatio, self.__useSSL)
        clusterEndpointCallback = ClusterEndpointCallback(
            self.__endpointPacketReactor)
        self.__networkManager.listenIn(listenningPort, clusterEndpointCallback,
                                       self.__useSSL)

        self.__statusMonitoringThread = ClusterStatusMonitoringThread(
            vmServerStatusUpdateInterval, self.__dbConnector,
            self.__networkManager, repositoryIP, repositoryPort,
            vmServerPacketHandler, imageRepositoryPacketHandler)
        self.__statusMonitoringThread.start()

    def monitorVMBootCommands(self):
        """
        Deletes the timed out virtual machine boot commands
        Args:
            None
        Returns:
            Nothing
        """

        while not self.__exit and not self.__endpointPacketReactor.hasFinished(
        ):
            data = self.__dbConnector.getOldVMBootCommandID(self.__timeout)
            if (data == None):
                sleep(1)
            else:
                self.__dbConnector.deleteActiveVMLocation(data[0])
                p = self.__packetHandler.createErrorPacket(
                    CLUSTER_SERVER_PACKET_T.VM_BOOT_FAILURE,
                    ERROR_DESC_T.CLSRVR_VM_BOOT_TIMEOUT, data[0])
                self.__networkManager.sendPacket('', self.__listenningPort, p)

    def closeNetworkConnections(self):
        """
        Closes the control connection
        Args:
            None
        Returns:
            Nothing
        """
        if (self.__statusMonitoringThread != None):
            self.__statusMonitoringThread.stop()
        self.__networkManager.stopNetworkService()
class ClusterServerMainReactor(object):
    '''
    This class is associated with the cluster server main reactor.
    '''
    def __init__(self, loadBalancerSettings, averageCompressionRatio, timeout):
        """
        Initializes the reactor's state
        Args:
            loadBalancerSettings: a list containing the load balancing algorithm settings
            averageCompressionRation: the compression algorithm's average compression ratio
            timeout: the virtual machine boot commands timeout
        """        
        self.__exit = False
        self.__loadBalancerSettings = loadBalancerSettings
        self.__averageCompressionRatio = averageCompressionRatio
        self.__timeout = timeout
        self.__statusMonitoringThread = None
        
    def connectToDatabase(self, mysqlRootsPassword, dbName, dbUser, dbPassword, scriptPath):
        """
        Establishes a connection with the cluster server database
        Args:
            mysqlRootsPassword: the MySQL root user's password
            dbName: a database name
            dbUser: a MySQL user name
            dbPassword: the user's password
            scriptPath: the schema definition script
        Returns:
            Nothing
        """
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(dbName, scriptPath, "root", mysqlRootsPassword) 
        configurator.addUser(dbUser, dbPassword, dbName, True)
        self.__dbConnector = ClusterServerDatabaseConnector(dbUser, dbPassword, dbName)
        self.__dbConnector.initializeVMServersStatus()
        
    def startListenning(self, useSSL, certificatePath, listenningPort, repositoryIP, repositoryPort, vmServerStatusUpdateInterval):
        """
        Creates the control connection
        Args:
            useSSL: indicates if SSL encryption must be used in the control connection or not
            certificatePath: the directory where the server.crt and server.key files are
            listenningPort: the control connection's port
            repositoryIP: the image repository IP address
            repositoryPort: the image repository's port
            vmServerStatusUpdateInterval: the virtual machine server status database interval
        Returns:
            Nothing
        """            
        
        self.__networkManager = NetworkManager(certificatePath)        
        self.__networkManager.startNetworkService()    
        self.__listenningPort = listenningPort
        self.__packetHandler = ClusterServerPacketHandler(self.__networkManager)    
        self.__useSSL = useSSL
        imageRepositoryPacketHandler = ImageRepositoryPacketHandler(self.__networkManager)
        vmServerPacketHandler = VMServerPacketHandler(self.__networkManager)        
        networkEventsReactor = NetworkEventsReactor(self.__dbConnector, repositoryIP, repositoryPort)
        
        
        imageRepositoryPacketReactor = ImageRepositoryPacketReactor(self.__dbConnector, self.__networkManager,
                                                                    listenningPort, repositoryIP, repositoryPort,
                                                                    self.__packetHandler, vmServerPacketHandler, imageRepositoryPacketHandler)
        try :
            imageRepositoryCallback = ImageRepositoryCallback(imageRepositoryPacketReactor, networkEventsReactor)
            self.__networkManager.connectTo(repositoryIP, repositoryPort, 10, imageRepositoryCallback, self.__useSSL, True)
            self.__dbConnector.addImageRepository(repositoryIP, repositoryPort, SERVER_STATE_T.READY) 
        except Exception as e:
            print "Can't connect to the image repository: " + e.message
            self.__exit = True
            return        
        
        vmServerPacketReactor = VMServerPacketReactor(self.__dbConnector, self.__networkManager, listenningPort,
                                                      vmServerPacketHandler, self.__packetHandler)
        
        self.__endpointPacketReactor = EndpointPacketReactor(self.__dbConnector, self.__networkManager, 
                                                             vmServerPacketHandler, self.__packetHandler,
                                                             imageRepositoryPacketHandler,
                                                             VMServerCallback(vmServerPacketReactor, networkEventsReactor),
                                                             listenningPort, repositoryIP, repositoryPort, self.__loadBalancerSettings,
                                                             self.__averageCompressionRatio, self.__useSSL) 
        clusterEndpointCallback = ClusterEndpointCallback(self.__endpointPacketReactor)
        self.__networkManager.listenIn(listenningPort, clusterEndpointCallback, self.__useSSL)
       
        self.__statusMonitoringThread = ClusterStatusMonitoringThread(vmServerStatusUpdateInterval,
                                                                      self.__dbConnector, self.__networkManager,
                                                                      repositoryIP, repositoryPort,
                                                                      vmServerPacketHandler, imageRepositoryPacketHandler)
        self.__statusMonitoringThread.start()           
    
    def monitorVMBootCommands(self):
        """
        Deletes the timed out virtual machine boot commands
        Args:
            None
        Returns:
            Nothing
        """
        
        while not self.__exit and not self.__endpointPacketReactor.hasFinished():
            data = self.__dbConnector.getOldVMBootCommandID(self.__timeout)
            if (data == None) :               
                sleep(1) 
            else :                
                self.__dbConnector.deleteActiveVMLocation(data[0])
                p = self.__packetHandler.createErrorPacket(CLUSTER_SERVER_PACKET_T.VM_BOOT_FAILURE, ERROR_DESC_T.CLSRVR_VM_BOOT_TIMEOUT, data[0])
                self.__networkManager.sendPacket('', self.__listenningPort, p)
    
    def closeNetworkConnections(self):
        """
        Closes the control connection
        Args:
            None
        Returns:
            Nothing
        """
        if (self.__statusMonitoringThread != None) :
            self.__statusMonitoringThread.stop()
        self.__networkManager.stopNetworkService()    
    print("\tquit: closes this application")
    print("\thelp: prints this help message")


if __name__ == "__main__":
    print('*' * 80)
    print('*' * 80)
    printLogo()
    print('Cluster Server tester')
    print('Version 7.0')
    print('*' * 80)
    print('*' * 80)
    print()
    networkManager = NetworkManager(".")
    networkManager.startNetworkService()
    pHandler = ClusterServerPacketHandler(networkManager)
    ip_address = raw_input("Cluster server IP address: ")
    port = raw_input("Cluster server control connection port: ")
    try:
        port = int(port)
        networkManager.connectTo(ip_address, port, 10,
                                 TesterCallback(pHandler), True)
        while not networkManager.isConnectionReady(ip_address, port):
            sleep(0.1)
        end = False
        while not end:
            command = raw_input('> ')
            tokens = command.split()
            end = process_command(tokens, networkManager, pHandler, ip_address,
                                  port)
class ClusterEndpointEntryPoint(object):  
    """
    These objects create, run and stop the cluster endpoint daemons.
    """    
    def __init__(self):
        """
        Initializes the daemon's state
        Args:
            None
        """
        self.__commandExecutionThread = None
        self.__updateRequestThread = None
        self.__codeTranslator = SpanishCodesTranslator()
        self.__commandsHandler = CommandsHandler(self.__codeTranslator)       
    
    def connectToDatabases(self, mysqlRootsPassword, endpointDBName, commandsDBName, endpointdbSQLFilePath, commandsDBSQLFilePath,
                           websiteUser, websiteUserPassword, endpointUser, endpointUserPassword, minCommandInterval):
        """
        Establishes the connection with the two databases
        Args:
            mysqlRootsPassword: the MySQL root's password
            endpointDBName: the endpoint database's name
            endpointdbSQLFilePath: the endpoint database's schema definition file path
            websiteUser: the web application's username
            websiteUserPassword: the web application's username
            endpointUser: the endpoint daemon user's name
            endpointUserPassword: the endpoint daemon user's password
        """        
        self.__rootsPassword = mysqlRootsPassword
        self.__statusDatabaseName = endpointDBName
        self.__commandsDatabaseName = commandsDBName
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(endpointDBName, endpointdbSQLFilePath, "root", mysqlRootsPassword)
        configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath, "root", mysqlRootsPassword)
        
        configurator.addUser(websiteUser, websiteUserPassword, endpointDBName, False)
        configurator.addUser(endpointUser, endpointUserPassword, endpointDBName, True)
        configurator.addUser(websiteUser, websiteUserPassword, commandsDBName, True)
        configurator.addUser(endpointUser, endpointUserPassword, commandsDBName, True)
        
        self.__commandsDBConnector = CommandsDatabaseConnector(endpointUser, endpointUserPassword, 
                                                               commandsDBName, minCommandInterval) 
        self.__endpointDBConnector = ClusterEndpointDBConnector(endpointUser, endpointUserPassword, endpointDBName)
        
    def connectToClusterServer(self, useSSL, certificatePath, clusterServerIP, clusterServerListenningPort, statusDBUpdateInterval,
                               commandTimeout, commandTimeoutCheckInterval):
        """
        Establishes a connection with the cluster server
        Args:
            certificatePath: the directory where the server.crt and server.key files are
            clusterServerIP: the cluster server's IP address
            clusterServerListenningPort: the cluster server commands connection's port
            statusDBUpdateInterval: the database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__networkManager = NetworkManager(certificatePath)
        self.__networkManager.startNetworkService()

        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__packetHandler = ClusterServerPacketHandler(self.__networkManager)     
        self.__commandsProcessor = CommandsProcessor(self.__commandsHandler, self.__packetHandler, self.__networkManager, 
                 self.__clusterServerIP, self.__clusterServerPort, self.__commandsDBConnector, self.__endpointDBConnector)
        packetReactor = ClusterEndpointPacketReactor(self.__codeTranslator, self.__commandsHandler, self.__packetHandler, self.__commandsProcessor,
                                                     self.__endpointDBConnector, self.__commandsDBConnector)
        try :
            self.__networkManager.connectTo(clusterServerIP, clusterServerListenningPort, 5, packetReactor, useSSL)
            while (not self.__networkManager.isConnectionReady(clusterServerIP, clusterServerListenningPort)) :
                sleep(0.1)                   
            self.__updateRequestThread = VMServerMonitoringThread(self.__packetHandler, self.__networkManager, self.__commandsProcessor, 
                                                                  self.__clusterServerIP, self.__clusterServerPort, statusDBUpdateInterval)
            self.__updateRequestThread.start()            
            self.__commandExecutionThread = CommandsMonitoringThread(self.__commandsDBConnector, commandTimeout, self.__commandsHandler, commandTimeoutCheckInterval)
            self.__commandExecutionThread.start()
        except NetworkManagerException as e :
            raise Exception(e.message)
        
    def doEmergencyStop(self):
        """
        Stops the endpoint daemon immediately
        Args:
            None
        Returns:
            Nothing
        """
        self.__networkManager.stopNetworkService()
        if (self.__updateRequestThread != None):
            self.__updateRequestThread.stop()
        if (self.__commandExecutionThread != None):
            self.__commandExecutionThread.stop()        
        
    def disconnectFromClusterServer(self):
        """
        Closes the connection with the cluster server
        Args:
            None
        Devuelve:
            Nada
        """
        p = self.__packetHandler.createHaltPacket(self.__commandsProcessor.haltVMServers())
        errorMessage = self.__networkManager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, p)
        NetworkManager.printConnectionWarningIfNecessary(self.__clusterServerIP, self.__clusterServerPort, "Cluster server halt", 
                                                         errorMessage)
        self.__updateRequestThread.stop()
        
        self.__commandExecutionThread.stop()
        
        self.closeNetworkConnections()
        
    def closeNetworkConnections(self):
        """
        Closes the network connections
        Args:
            None
        Returns:
            Nothing
        """
        self.__networkManager.stopNetworkService()
        
    def processCommands(self):
        """
        Processes the users' requests
        Args:
            None
        Returns:
            Nothing
        """
        self.__commandsProcessor.processCommands()