Пример #1
0
def killProcess(agent, user, password, pid):
    s = Session(agent, service="ProcessStop")
    s.authorize(user, password)

    response = s.doRequest(attributes={"PID" : str(pid)})

    return int(ElementTree.fromstring(response).get("ExitCode"))
Пример #2
0
def stopProcess(address, port, dbPassword):
    s = Session(address, port=port, service="Monitor")
    s.authorize("Cloud", dbPassword)
    s.doConnect()

    s.send("<Request Action=\"shutdown\"/>")

    s.close()
Пример #3
0
    def query(self, type, msgBody=None):
        s = Session(self.getPeer().getConnectStr(), service="Manager")
        s.authorize(self.getPeer().getDomain().getUser(), self.getPeer().getDomain().getPassword())
        pwdResponse = s.doRequest(attributes={"Type": "GetDatabaseCredentials", "Database": self.getDbName()})

        pwdXml = ElementTree.fromstring(pwdResponse)
        pwd = pwdXml.find("Password").text.strip()

        return queryEngine(self.getAddress(), self.getPort(), type, pwd, msgBody)
Пример #4
0
 def test_timeout(self):
     """
     tests timeout function- includes a print message
     """
     user6 = User(2859459814, '7386', 10000)
     Session.authorize(self.session, user6, '7386')
     Session.timeout(self.session, user6, 1597428189999999990.6783)
     self.assertEqual("Authorization required",
                      Session.get_user_balance(self.session, user6))
Пример #5
0
    def query(self, query_type, msg_body=None):
        session = Session(self.peer.connect_str, service="Manager")
        session.authorize(self.peer.domain.user, self.peer.domain.password)
        pwd_response = session.doRequest(attributes={"Type": "GetDatabaseCredentials", "Database": self.database.name})

        pwd_xml = ElementTree.fromstring(pwd_response)
        pwd = pwd_xml.find("Password").text.strip()

        return queryEngine(self.address, self.port, query_type, pwd, msg_body)
Пример #6
0
    def query(self, query_type, msg_body=None):
        session = Session(self.peer.domain.entry_peer.connect_str, service="Manager")
        session.authorize(self.peer.domain.user, self.peer.domain.password)
        pwd_response = session.doRequest(attributes={"Type": "GetDatabaseCredentials",
                                                     "Database": self.database.name})

        pwd_xml = ElementTree.fromstring(pwd_response)
        pwd = pwd_xml.find("Password").text.strip()

        return queryEngine(self.address, self.port, query_type, pwd, msg_body)
Пример #7
0
 def test_logout(self):
     """
     tests logout function- simple logout, and logout when no one is logged in
     """
     user6 = User(2859459814, '7386', 10000)
     Session.authorize(self.session, user6, '7386')
     msg = Session.logout(self.session, user6)
     self.assertEqual("Account 2859459814 logged out", msg)
     self.assertEqual("No account is currently authorized",
                      Session.logout(self.session, user6))
Пример #8
0
 def test_deposit(self):
     """
     tests the deposit function- if everything goes well and if authorization is required
     """
     user1 = User(2001377812, '5950', 10000)
     Session.authorize(self.session, user1, '5950')
     a = datetime.now()
     success = Session.deposit(self.session, self.machine, user1, 50, a)
     self.assertEqual(success, "Current balance: 10050")
     Session.logout(self.session, user1)
     self.assertEqual(
         "Authorization required",
         Session.deposit(self.session, self.machine, user1, 50, a))
Пример #9
0
def doDatabaseAction(broker, user, password, db_name, action, child=None):
    s = Session(broker, service="ChorusManagement")
    s.authorize(user, password)

    if child is not None:
        child = [ child ]
    s.doConnect(attributes={"Database" : db_name, "Action" : action}, children=child)
    response = s.recv()
    checkForError(response)

    s.close()

    return response
Пример #10
0
 def test_authorize(self):
     """
     Tests the authorize function- pass, fail and does not exist
     """
     user1 = User(2001377812, '5950', 0)
     user2 = User(2001377812, '0075', 0)
     user3 = User(1203939932, '0075', 0)
     pas = Session.authorize(self.session, user1, '5950')
     fail = Session.authorize(self.session, user2, '0075')
     notexist = Session.authorize(self.session, user3, '0075')
     self.assertEqual(pas, "2001377812 successfully authorized")
     self.assertEqual(fail, "Authorization failed")
     self.assertEqual(notexist, "Authorization failed")
Пример #11
0
def monitorEngine(address, port, dbPassword, listener=None):
    if not listener:
        listener = _StandardOutListener()

    s = Session(address, port=port, service="Monitor")
    s.authorize("Cloud", dbPassword)

    monitor = SessionMonitor(s, listener=listener)
    monitor.start()

    s.doConnect()

    return EngineMonitor(monitor, s)
Пример #12
0
def monitorDomainStats(broker, user, password, listener=None):
    if not listener:
        listener = _StandardOutListener()

    s = Session(broker, service="HostStats")
    s.authorize(user, password)

    s.doConnect()
    checkForError(s.recv())

    monitor = SessionMonitor(s, listener=listener)
    monitor.start()

    return monitor
Пример #13
0
def getArchiveHistory(agent, user, password, archive, options=None):
    s = Session(agent, service="ProcessStart")
    s.authorize(user, password)

    option = _OPTION_VALUE_STR % ("--archive", archive)
    opts = [ ElementTree.fromstring(option) ]

    if options:
        for (k,v) in options:
            if v:
                option = _OPTION_VALUE_STR % (k, v)
            else:
                option = _OPTION_FLAG_STR % k
            opts.append(ElementTree.fromstring(option))

    return s.doRequest(attributes={"Process" : "archiveHistory"}, children=opts)
Пример #14
0
def startProcess(agent, user, password, db_name, options=None):
    s = Session(agent, service="ProcessStart")
    s.authorize(user, password)

    if not options:
        options = []

    options.append(("--database", db_name))

    opts = []
    for (k,v) in options:
        if v:
            optStr = _OPTION_VALUE_STR % (k, v)
        else:
            optStr = _OPTION_FLAG_STR % k
        opts.append(ElementTree.fromstring(optStr))

    return s.doRequest(attributes={"Process" : "server"}, children=opts)
Пример #15
0
def queryEngine(address, port, target, dbPassword, msgBody=None):
    s = Session(address, port=port, service="Query")
    s.authorize("Cloud", dbPassword)
    s.doConnect()

    msg = "<Query Target=\"%s\"/>" % target
    if msgBody is not None:
        xml = ElementTree.fromstring(msg)
        xml.append(msgBody)
        msg = ElementTree.tostring(xml)

    s.send(msg)
    response = s.recv()

    checkForError(response)

    s.close()

    return response
Пример #16
0
 def test_balance(self):
     """
     tests the get_user_balance function- positive, negative and zero balance
     also when authorization is required
     """
     user1 = User(2001377812, '5950', 10000)
     Session.authorize(self.session, user1, '5950')
     Session.withdraw(self.session, self.machine, user1, 400,
                      datetime.now())
     Session.withdraw(self.session, self.machine, user1, 160,
                      datetime.now())
     Session.deposit(self.session, self.machine, user1, 400, datetime.now())
     self.assertEqual('Current balance: 9840',
                      Session.get_user_balance(self.session, user1))
     user2 = User(2001377812, '5950', 0)
     Session.authorize(self.session, user2, '5950')
     self.assertEqual('Current balance: 0',
                      Session.get_user_balance(self.session, user2))
     user3 = User(2001377812, '5950', -2020)
     Session.authorize(self.session, user2, '5950')
     self.assertEqual('Current balance: -2020',
                      Session.get_user_balance(self.session, user3))
     Session.logout(self.session, user3)
     self.assertEqual("Authorization required",
                      Session.get_user_balance(self.session, user3))
Пример #17
0
 def test_get_history(self):
     """
     tests the get_history function- for empty and valid history, and for authorization required
     """
     user1 = User(2001377812, '5950', 10000)
     Session.authorize(self.session, user1, '5950')
     self.assertEqual("No history found",
                      Session.get_history(self.session, user1))
     a = datetime.now()
     Session.withdraw(self.session, self.machine, user1, 400, a)
     a = a.strftime("%d/%m/%Y %H:%M:%S")
     b = datetime.now()
     Session.withdraw(self.session, self.machine, user1, 160, b)
     b = b.strftime("%d/%m/%Y %H:%M:%S")
     c = datetime.now()
     Session.deposit(self.session, self.machine, user1, 400, c)
     c = c.strftime("%d/%m/%Y %H:%M:%S")
     x = Session.get_history(self.session, user1)
     string = "\n%s 400 9840\n%s -160 9440\n%s -400 9600" % (a, b, c)
     self.assertEqual(string, x)
     Session.logout(self.session, user1)
     self.assertEqual("Authorization required",
                      Session.get_history(self.session, user1))
Пример #18
0
    def find_peer(self, address, port=None):
        """
        Find a peer by address
        @type: address str
        @type: port int or str
        @rtype: Peer
        """
        if port is None:
            if ":" in address:
                address, port = address.split(":", 2)
            else:
                port = self.__entry_peer.port
        else:
            if ":" in address:
                address, _ = address.split(":", 2)

        ip = socket.gethostbyname(address)
        inet_sock_addr = ":".join([ip, str(port)])
        try:
            return self.__peers_by_addr[inet_sock_addr]
        except:
            pass

        session = Session(address, port=port, service="Identity")
        session.authorize(self.__user, self.__password)
        response = session.doRequest()
        try:
            root = ElementTree.fromstring(response)
            if self.__domain_name != root.get("Domain"):
                return None
            peer = self.get_peer(root.get("AgentId"))
            if peer:
                self.__peers_by_addr[peer._get_normalized_addr()] = peer
            return peer
        except:
            return None
Пример #19
0
 def _send_domain_message(self, service, attributes=None, text=None, children=None):
     session = Session(self.__entry_peer.address, port=self.__entry_peer.port, service=service)
     session.authorize(self.__user, self.__password)
     return session.doRequest(attributes, text, children)
Пример #20
0
class Domain(BaseListener):
    """Represents the NuoDB domain.
    
    The domain is the top level NuoDB management object. The domain object 
    provides access to the peers and databases that are contained within.
    """

    def __init__(self, broker_addr, domain_user, domain_pwd, listener=None):
        """
        @type broker_addr str
        @type domain_user str
        @type domain_pwd str
        @type listener
        """
        if not domain_pwd:
            raise Exception("A password is required to join a domain")

        self.__session = Session(broker_addr, service="Monitor")
        self.__session.authorize(domain_user, domain_pwd)

        self.__user = domain_user
        self.__password = domain_pwd
        self.__listener = listener
        self.__peers = dict()
        """ @type : dict[str, Peer] """
        self.__databases = dict()
        """ @type : dict[str, Database] """

        self.__monitor = SessionMonitor(self.__session, self)
        
        # These will be set in handle status after joining the domain 
        self.__domain_name = None
        """ @type : str """
        self.__entry_peer = None
        """ @type : Peer """

        try:
            self.__session.doConnect()
            self.__handle_status(self.__session.recv())
        except Exception:
            self.__monitor.close()
            raise

        self.__monitor.start()

    def __str__(self):
        return self.domain_name + " [Entered through: " + self.entry_peer.connect_str + "]"

    def disconnect(self):
        """Disconnect from the domain."""
        self.__monitor.close()
        
    def _send_domain_message(self, service, attributes=None, text=None, children=None):
        session = Session(self.__entry_peer.address, port=self.__entry_peer.port, service=service)
        session.authorize(self.__user, self.__password)
        return session.doRequest(attributes, text, children)

    @property
    def user(self):
        """Return the domain user."""
        return self.__user

    @property
    def password(self):
        """Return the domain password."""
        return self.__password
    
    @property
    def domain_name(self):
        """Return the domain name."""
        return self.__domain_name

    def find_peer(self, address):
        """
        Find a peer by address
        @type: address str
        @rtype: Peer
        """

    def get_peer(self, agent_id):
        """
        Return a peer for a given agent_id.
        @type agent_id str
        @rtype: Peer
        """
        return self.__peers.get(agent_id)

    @property
    def peers(self):
        """
        Return a list of all peers in the domain.
        @rtype: list[Peer]
        """
        return self.__peers.values()

    @property
    def entry_peer(self):
        """
        Return the peer that was used to enter the domain.
        @rtype: Peer
        """
        return self.__entry_peer

    def get_database(self, name):
        """
        Return a database by name
        @type name str
        @rtype: Database
        """
        return self.__databases.get(name)

    @property
    def databases(self):
        """
        Return a list of databases in the domain
        @rtype: list[Database]
        """
        return self.__databases.values()

    def create_template(self, template_name, summary, requirements):
        """Create template by name"""
        response = self._send_domain_message(**Template.build_create_request(template_name, summary, requirements))
        return ElementTree.fromstring(response).tag == Template.success_message

    def update_template(self, template_name, summary, requirements):
        """Update template by name"""
        response = self._send_domain_message(**Template.build_update_request(template_name, summary, requirements))
        return ElementTree.fromstring(response).tag == Template.success_message

    def delete_template(self, template_name):
        """Delete template by name"""
        response = self._send_domain_message(**Template.build_delete_request(template_name))
        return ElementTree.fromstring(response).tag == Template.success_message

    def get_template(self, template_name):
        """Return a template by name"""
        response = self._send_domain_message(**Template.build_get_request(template_name))
        return Template.from_message(response)

    @property
    def templates(self):
        """Return a list of templates in the domain"""
        response = self._send_domain_message(**Template.build_list_request())
        return Template.from_list_message(response)

    def create_description(self, name, template_name, variables, dba_user, dba_password):
        response = self._send_domain_message(**Description.build_create_request(name, template_name, variables, dba_user, dba_password))
        return ElementTree.fromstring(response).tag == Description.success_message

    def update_description(self, name, template_name, variables):
        response = self._send_domain_message(**Description.build_update_request(name, template_name, variables))
        return ElementTree.fromstring(response).tag == Description.success_message

    def delete_description(self, name):
        response = self._send_domain_message(**Description.build_delete_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    def get_description(self, name):
        response = self._send_domain_message(**Description.build_get_request(name))
        return Description.from_message(response)

    def start_description(self, name):
        response = self._send_domain_message(**Description.build_start_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    def stop_description(self, name):
        response = self._send_domain_message(**Description.build_stop_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    @property
    def descriptions(self):
        response = self._send_domain_message(**Description.build_list_request())
        return Description.from_list_message(response)

    def shutdown(self, graceful=True):
        """Shutdown all databases in the domain.
        
        graceful -- (default True) means that the database will first
        be quiesced and then shutdown.
        """
        for database in self.__databases.itervalues():
            database.shutdown(graceful)

    def message_received(self, root):
        """Process a management message from the broker.
        
        Override from session.BaseListener.
        """
        if root.tag == "Event":
            event_type = root.get("Type")
            if event_type == "NewBroker":
                self.__peer_joined(Peer.from_message(self, root.find("Broker")))
            elif event_type == "BrokerExit":
                self.__peer_left(Peer.from_message(self, root.find("Broker")))
            elif event_type == "StatusChanged":
                status = root.get("Status")

                process_element = root.find("Process")
                db = self.__databases[process_element.get("Database")]
                process = Process.from_message(db, process_element)

                self.__process_status_changed(process, status)
            elif event_type == "ProcessFailed":
                peer = Peer.from_message(self, root.find("Broker"))
                peer = self.get_peer(peer.id)

                reason = root.get("Reason")
                start_id = root.get("StartId")

                self.__process_failed(peer, start_id, reason)
            elif event_type == "NewProcess" or event_type == "ProcessExit":
                process_element = root.find("Process")
                db_name = process_element.get("Database")

                if db_name not in self.__databases:
                    self.__databases[db_name] = Database(self, db_name)
                    if self.__listener:
                        try:
                            self.__listener.database_joined(self.__databases[db_name])
                        except AttributeError:
                            pass
                            

                if event_type == "NewProcess":
                    start_id = process_element.get("StartId")
                    self.__process_joined(Process.from_message(self.__databases[db_name],
                                                       process_element), start_id)
                else:
                    self.__process_left(Process.from_message(self.__databases[db_name],
                                                     process_element))

    def closed(self):
        """Called when the session is closed.
        
        Override from session.BaseListener.
        """
        if self.__listener:
            try:
                self.__listener.closed()
            except AttributeError:
                pass

    def __handle_status(self, message):
        """Handle initial domain status on domain connection.
        
        Note that this is ONLY for processing the initial status message. All
        further update messages are processed by message_received()."""
        root = ElementTree.fromstring(message)
        if root.tag != "Status":
            raise Exception("Expected status message; got " + root.tag)

        self.__domain_name = root.get("Domain")

        self.__entry_peer = Peer(self, self.__session.address, root.get("AgentId"),
                                (root.get("Role") == "Broker"), self.__session.port,
                                root.get("Hostname"), root.get("Version"))
        self.__peer_joined(self.__entry_peer)

        for child in list(root):
            if child.tag == "Broker":
                self.__peer_joined(Peer.from_message(self, child))

        for child in list(root):
            if child.tag == "Database":
                name = child.get("Name")
                if self.__listener:
                    try:
                        self.__listener.database_joined(self.__databases[name])
                    except AttributeError:
                        pass

                for process_element in list(child):
                    if process_element.tag == "Process":
                        if name not in self.__databases:
                            self.__databases[name] = Database(self, name)
                        self.__process_joined(Process.from_message(self.__databases[name], process_element), None)

    def __peer_joined(self, peer):
        """Called when a peer joins the domain."""
        self.__peers[peer.id] = peer
        if self.__listener:
            try:
                self.__listener.peer_joined(peer)
            except AttributeError:
                pass

    def __peer_left(self, peer):
        """Called when a peer leaves the domain."""
        del self.__peers[peer.id]
        if self.__listener:
            try:
                self.__listener.peer_left(peer)
            except AttributeError:
                pass

    def __process_joined(self, process, start_id):
        """Called when a process joins the domain."""
        process.database._add_process(process)
        process.peer._notify_start_id(start_id, process)
        if self.__listener:
            try:
                self.__listener.process_joined(process)
            except AttributeError:
                pass
    
    def __process_left(self, process):
        """Called when a process leaves the domain."""
        database = process.database
        database._remove_process(process)
        process.peer._remove_process(process)
        if self.__listener:
            try:
                self.__listener.process_left(process)
            except AttributeError:
                pass

        if len(database.processes) == 0:
            del self.__databases[database.name]
            if self.__listener:
                try:
                    self.__listener.database_left(database)
                except AttributeError:
                    pass

    def __process_failed(self, peer, start_id, reason):
        """Called when a process in the domain fails."""
        peer._notify_start_id(start_id, reason)
        if self.__listener:
            try:
                self.__listener.process_failed(peer, reason)
            except AttributeError:
                pass

    def __process_status_changed(self, process, status):
        """Called when a process in the domain changes status."""
        process._set_status(status)
        if self.__listener:
            try:
                self.__listener.process_status_changed(process, status)
            except AttributeError:
                pass


    def _send_management_message(self, message, peer, process):
        """Send a management message.
        
        Note that this is an initial verison only to support the shutdown 
        routine that doesn't need to watch for return messages ... right now 
        this module is only supporting the tests, which don't need the other 
        management routines at this point, so we'll flesh this out (as in the 
        Java implementation) in the second round when other utilites get 
        updated as well
        """
        root = ElementTree.fromstring("<ManagementRequest AgentId=\"%s\" ProcessId=\"%i\"/>" % (peer.id, process.pid))
        root.append(message)

        self.__session.send(ElementTree.tostring(root))
Пример #21
0
def main():
    """
    this is the main function- it creates a machine, and asks the user for input
    """
    machine = Machine()
    machine.set_balance(10000)
    session = Session()
    Session.set_dict(session)

    input_var = None
    try:
        input_var = eval(
            input("Welcome to the ATM- please enter your user id "))
        input_var = int(input_var)
    except (SyntaxError, NameError, TypeError):
        print("Not a valid input")

    if input_var in session.dic:
        bal = session.dic[input_var][1]
        try:
            pin = input("Please enter your pin ")
        except (SyntaxError, NameError, TypeError):
            print("Not a valid pin")
            pin = '0000'
        user = User(input_var, pin, bal)
        print((Session.authorize(session, user, pin)))
        amount = None
        actions = {
            1: ["withdraw", 4],
            2: ["deposit", 4],
            3: ["get_user_balance", 1],
            4: ["get_history", 1],
            5: ["logout", 1],
            6: ["end", 0]
        }
        action = None
        if session.session_active:
            #Validating input so we can avoid syntaxerrors
            try:
                action = eval(
                    input(
                        "What would you like to do today? Select a number: \n 1: Withdraw \n 2: Deposit \n 3: Check balance \n 4: Check history \n 5. Log out \n 6. Shut down "
                    ))
                action = int(action)
            except (SyntaxError, NameError, TypeError):
                print("Not a valid input")
            while action:
                session.timeout(user, time.time())
                try:
                    action = int(action)
                except (SyntaxError, NameError, TypeError):
                    print("Not a valid input")
                if action not in list(actions.keys()):
                    action = eval(input("Not a valid input, try again "))
                else:
                    func = actions[action][0]
                    params = actions[action][1]
                    if params == 4:
                        if func == "withdraw":
                            # Validating input so we can avoid syntaxerrors
                            try:
                                amount = eval(
                                    input(
                                        "Please enter an amount (multiple of $20) to withdraw "
                                    ))
                                amount = int(amount)
                                assert (amount > 0)
                            except (SyntaxError, NameError, TypeError,
                                    AssertionError):
                                amount = 0
                                print("Not a valid amount")
                        else:
                            # Validating input so we can avoid syntaxerrors
                            try:
                                amount = eval(
                                    input(
                                        "Please enter an amount to deposit "))
                                amount = int(amount)
                                assert (amount > 0)
                            except (SyntaxError, NameError, AssertionError):
                                amount = 0
                                print("Not a valid amount")
                        print((getattr(Session, func)(session, machine, user,
                                                      amount, datetime.now())))
                    elif params == 1:
                        print((getattr(Session, func)(session, user)))
                    else:
                        print((getattr(Session, func)(session)))
                try:
                    action = eval(
                        input(
                            "Anything else? Select a number: \n 1: Withdraw \n 2: Deposit \n 3: Check balance \n 4: Check history \n 5. Log out \n 6. End "
                        ))
                except (SyntaxError, NameError, TypeError):
                    print("Not a valid input- exiting program")
                    print(Session.end(session))

    else:
        print("Sorry, you are not a user of this bank ")
Пример #22
0
def getState(broker, user, password):
    s = Session(broker, service="State")
    s.authorize(user, password)
    
    return s.doRequest()
Пример #23
0
def setLicense(broker, user, password, licenseText):
    s = Session(broker, service="License")
    s.authorize(user, password)

    s.doRequest(attributes={ "Action" : "ApplyLicense" }, text=licenseText)
Пример #24
0
def getLicense(broker, user, password):
    s = Session(broker, service="License")
    s.authorize(user, password)

    return s.doRequest(attributes={ "Action" : "GetCurrentLicense" })
Пример #25
0
 def _send_domain_message(self, service, attributes=None, text=None, children=None):
     session = Session(self.__entry_peer.address, port=self.__entry_peer.port, service=service)
     session.authorize(self.__user, self.__password)
     return session.doRequest(attributes, text, children)
Пример #26
0
class Domain(BaseListener):
    """Represents the NuoDB domain.
    
    The domain is the top level NuoDB management object. The domain object 
    provides access to the peers and databases that are contained within.
    """

    def __init__(self, broker_addr, domain_user, domain_pwd, listener=None):
        """
        @type broker_addr str
        @type domain_user str
        @type domain_pwd str
        @type listener
        """
        if not domain_pwd:
            raise Exception("A password is required to join a domain")

        self.__session = Session(broker_addr, service="Monitor")
        self.__session.authorize(domain_user, domain_pwd)

        self.__user = domain_user
        self.__password = domain_pwd
        self.__listener = listener
        self.__peers = dict()
        """ @type : dict[str, Peer] """
        self.__databases = dict()
        """ @type : dict[str, Database] """

        self.__monitor = SessionMonitor(self.__session, self)
        
        # These will be set in handle status after joining the domain 
        self.__domain_name = None
        """ @type : str """
        self.__entry_peer = None
        """ @type : Peer """

        try:
            self.__session.doConnect()
            self.__handle_status(self.__session.recv())
        except Exception:
            self.__monitor.close()
            raise

        self.__monitor.start()

    def __str__(self):
        return self.domain_name + " [Entered through: " + self.entry_peer.connect_str + "]"

    def disconnect(self):
        """Disconnect from the domain."""
        self.__monitor.close()
        
    def _send_domain_message(self, service, attributes=None, text=None, children=None):
        session = Session(self.__entry_peer.address, port=self.__entry_peer.port, service=service)
        session.authorize(self.__user, self.__password)
        return session.doRequest(attributes, text, children)

    @property
    def user(self):
        """Return the domain user."""
        return self.__user

    @property
    def password(self):
        """Return the domain password."""
        return self.__password
    
    @property
    def domain_name(self):
        """Return the domain name."""
        return self.__domain_name

    def find_peer(self, address):
        """
        Find a peer by address
        @type: address str
        @rtype: Peer
        """

    def get_peer(self, agent_id):
        """
        Return a peer for a given agent_id.
        @type agent_id str
        @rtype: Peer
        """
        return self.__peers.get(agent_id)

    @property
    def peers(self):
        """
        Return a list of all peers in the domain.
        @rtype: list[Peer]
        """
        return self.__peers.values()

    @property
    def entry_peer(self):
        """
        Return the peer that was used to enter the domain.
        @rtype: Peer
        """
        return self.__entry_peer

    def get_database(self, name):
        """
        Return a database by name
        @type name str
        @rtype: Database
        """
        return self.__databases.get(name)

    @property
    def databases(self):
        """
        Return a list of databases in the domain
        @rtype: list[Database]
        """
        return self.__databases.values()

    def create_template(self, template_name, summary, requirements):
        """Create template by name"""
        response = self._send_domain_message(**Template.build_create_request(template_name, summary, requirements))
        return ElementTree.fromstring(response).tag == Template.success_message

    def update_template(self, template_name, summary, requirements):
        """Update template by name"""
        response = self._send_domain_message(**Template.build_update_request(template_name, summary, requirements))
        return ElementTree.fromstring(response).tag == Template.success_message

    def delete_template(self, template_name):
        """Delete template by name"""
        response = self._send_domain_message(**Template.build_delete_request(template_name))
        return ElementTree.fromstring(response).tag == Template.success_message

    def get_template(self, template_name):
        """Return a template by name"""
        response = self._send_domain_message(**Template.build_get_request(template_name))
        return Template.from_message(response)

    @property
    def templates(self):
        """Return a list of templates in the domain"""
        response = self._send_domain_message(**Template.build_list_request())
        return Template.from_list_message(response)

    def create_description(self, name, template_name, variables, dba_user, dba_password):
        response = self._send_domain_message(**Description.build_create_request(name, template_name, variables, dba_user, dba_password))
        return ElementTree.fromstring(response).tag == Description.success_message

    def update_description(self, name, template_name, variables):
        response = self._send_domain_message(**Description.build_update_request(name, template_name, variables))
        return ElementTree.fromstring(response).tag == Description.success_message

    def delete_description(self, name):
        response = self._send_domain_message(**Description.build_delete_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    def get_description(self, name):
        response = self._send_domain_message(**Description.build_get_request(name))
        return Description.from_message(response)

    def start_description(self, name):
        response = self._send_domain_message(**Description.build_start_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    def stop_description(self, name):
        response = self._send_domain_message(**Description.build_stop_request(name))
        return ElementTree.fromstring(response).tag == Description.success_message

    @property
    def descriptions(self):
        response = self._send_domain_message(**Description.build_list_request())
        return Description.from_list_message(response)

    def shutdown(self, graceful=True):
        """Shutdown all databases in the domain.
        
        graceful -- (default True) means that the database will first
        be quiesced and then shutdown.
        """
        for database in self.__databases.itervalues():
            database.shutdown(graceful)

    def message_received(self, root):
        """Process a management message from the broker.
        
        Override from session.BaseListener.
        """
        if root.tag == "Event":
            event_type = root.get("Type")
            if event_type == "NewBroker":
                self.__peer_joined(Peer.from_message(self, root.find("Broker")))
            elif event_type == "BrokerExit":
                self.__peer_left(Peer.from_message(self, root.find("Broker")))
            elif event_type == "StatusChanged":
                status = root.get("Status")

                process_element = root.find("Process")
                db = self.__databases[process_element.get("Database")]
                process = Process.from_message(db, process_element)

                self.__process_status_changed(process, status)
            elif event_type == "ProcessFailed":
                peer = Peer.from_message(self, root.find("Broker"))
                peer = self.get_peer(peer.id)

                reason = root.get("Reason")
                start_id = root.get("StartId")

                self.__process_failed(peer, start_id, reason)
            elif event_type == "NewProcess" or event_type == "ProcessExit":
                process_element = root.find("Process")
                db_name = process_element.get("Database")

                if db_name not in self.__databases:
                    self.__databases[db_name] = Database(self, db_name)
                    if self.__listener:
                        try:
                            self.__listener.database_joined(self.__databases[db_name])
                        except AttributeError:
                            pass
                            

                if event_type == "NewProcess":
                    start_id = process_element.get("StartId")
                    self.__process_joined(Process.from_message(self.__databases[db_name],
                                                       process_element), start_id)
                else:
                    self.__process_left(Process.from_message(self.__databases[db_name],
                                                     process_element))

    def closed(self):
        """Called when the session is closed.
        
        Override from session.BaseListener.
        """
        if self.__listener:
            try:
                self.__listener.closed()
            except AttributeError:
                pass

    def __handle_status(self, message):
        """Handle initial domain status on domain connection.
        
        Note that this is ONLY for processing the initial status message. All
        further update messages are processed by message_received()."""
        root = ElementTree.fromstring(message)
        if root.tag != "Status":
            raise Exception("Expected status message; got " + root.tag)

        self.__domain_name = root.get("Domain")

        self.__entry_peer = Peer(self, self.__session.address, root.get("AgentId"),
                                (root.get("Role") == "Broker"), self.__session.port,
                                root.get("Hostname"), root.get("Version"))
        self.__peer_joined(self.__entry_peer)

        for child in list(root):
            if child.tag == "Broker":
                self.__peer_joined(Peer.from_message(self, child))

        for child in list(root):
            if child.tag == "Database":
                name = child.get("Name")
                if self.__listener:
                    try:
                        self.__listener.database_joined(self.__databases[name])
                    except AttributeError:
                        pass

                for process_element in list(child):
                    if process_element.tag == "Process":
                        if name not in self.__databases:
                            self.__databases[name] = Database(self, name)
                        self.__process_joined(Process.from_message(self.__databases[name], process_element), None)

    def __peer_joined(self, peer):
        """Called when a peer joins the domain."""
        self.__peers[peer.id] = peer
        if self.__listener:
            try:
                self.__listener.peer_joined(peer)
            except AttributeError:
                pass

    def __peer_left(self, peer):
        """Called when a peer leaves the domain."""
        del self.__peers[peer.id]
        if self.__listener:
            try:
                self.__listener.peer_left(peer)
            except AttributeError:
                pass

    def __process_joined(self, process, start_id):
        """Called when a process joins the domain."""
        process.database._add_process(process)
        process.peer._notify_start_id(start_id, process)
        if self.__listener:
            try:
                self.__listener.process_joined(process)
            except AttributeError:
                pass
    
    def __process_left(self, process):
        """Called when a process leaves the domain."""
        database = process.database
        database._remove_process(process)
        process.peer._remove_process(process)
        if self.__listener:
            try:
                self.__listener.process_left(process)
            except AttributeError:
                pass

        if len(database.processes) == 0:
            del self.__databases[database.name]
            if self.__listener:
                try:
                    self.__listener.database_left(database)
                except AttributeError:
                    pass

    def __process_failed(self, peer, start_id, reason):
        """Called when a process in the domain fails."""
        peer._notify_start_id(start_id, reason)
        if self.__listener:
            try:
                self.__listener.process_failed(peer, reason)
            except AttributeError:
                pass

    def __process_status_changed(self, process, status):
        """Called when a process in the domain changes status."""
        process._set_status(status)
        if self.__listener:
            try:
                self.__listener.process_status_changed(process, status)
            except AttributeError:
                pass


    def _send_management_message(self, message, peer, process):
        """Send a management message.
        
        Note that this is an initial verison only to support the shutdown 
        routine that doesn't need to watch for return messages ... right now 
        this module is only supporting the tests, which don't need the other 
        management routines at this point, so we'll flesh this out (as in the 
        Java implementation) in the second round when other utilites get 
        updated as well
        """
        root = ElementTree.fromstring("<ManagementRequest AgentId=\"%s\" ProcessId=\"%i\"/>" % (peer.id, process.pid))
        root.append(message)

        self.__session.send(ElementTree.tostring(root))
Пример #27
0
    def test_withdrawal(self):
        """
        tests the deposit function- check overdraft, not multiple of 200, whether the machine is empty,
        whether the machine has enough money, whether the user has enough money
        """
        user1 = User(7089382418, '0075', 100)
        Session.authorize(self.session, user1, '0075')
        a = datetime.now()
        Session.withdraw(self.session, self.machine, user1, 400, a)
        b = datetime.now()
        overdrawn = Session.withdraw(self.session, self.machine, user1, 160, b)
        self.assertEqual(
            "Your account is overdrawn! You may not make withdrawals at this time.",
            overdrawn)

        user2 = User(2001377812, '5950', 100)
        Session.authorize(self.session, user2, '5950')
        c = datetime.now()
        not_multiple = Session.withdraw(self.session, self.machine, user2, 412,
                                        c)
        self.assertEqual("Unable to process your withdrawal at this time.",
                         not_multiple)

        self.machine.set_balance(0)
        empty_machine = Session.withdraw(self.session, self.machine, user2,
                                         412, c)
        self.assertEqual("Unable to process your withdrawal at this time.",
                         empty_machine)

        #overdraft tests
        user3 = User(2001377812, '5950', 100)
        Session.authorize(self.session, user3, '5950')
        self.machine.set_balance(120)
        not_enough_in_machine_or_user = Session.withdraw(
            self.session, self.machine, user3, 400, c)
        string = "Unable to dispense full amount requested at this time\n Amount dispensed: 120 \n You have been charged an overdraft fee of $5. Current balance: -25"
        self.assertEqual(not_enough_in_machine_or_user, string)

        user4 = User(2001377812, '5950', 100)
        Session.authorize(self.session, user4, '5950')
        self.machine.set_balance(10000)
        not_enough_in_user = Session.withdraw(self.session, self.machine,
                                              user4, 300, c)
        string = "Amount dispensed: 300 \n You have been charged an overdraft fee of $5. Current balance: -205"
        self.assertEqual(not_enough_in_user, string)

        user5 = User(2001377812, '5950', 10000)
        Session.authorize(self.session, user5, '5950')
        self.machine.set_balance(300)
        not_enough_money_in_machine = Session.withdraw(self.session,
                                                       self.machine, user5,
                                                       600, c)
        string = "Unable to dispense full amount requested at this time\n Amount dispensed: 300 \. Current balance: 9700"
        self.assertEqual(not_enough_money_in_machine, string)

        #all goes well
        user6 = User(2001377812, '5950', 10000)
        Session.authorize(self.session, user6, '5950')
        self.machine.set_balance(10000)
        success = Session.withdraw(self.session, self.machine, user6, 600, c)
        string = "Amount dispensed: 600 \n Current balance: 9400"
        self.assertEqual(success, string)

        #authorization required
        Session.logout(self.session, user6)
        self.assertEqual(
            "Authorization required",
            Session.withdraw(self.session, self.machine, user6, 20, c))
Пример #28
0
class Domain(BaseListener):
    def __init__(self, brokerAddr, domainUser, domainPwd, listener=None):
        if not domainPwd:
            raise Exception("A password is required to join a domain")

        self.__session = Session(brokerAddr, service="Monitor")
        self.__session.authorize(domainUser, domainPwd)

        self.__user = domainUser
        self.__password = domainPwd
        self.__listener = listener
        self.__peers = dict()
        self.__databases = dict()

        self.__monitor = SessionMonitor(self.__session, self)

        try:
            self.__session.doConnect()
            self.__handleStatus(self.__session.recv())
        except Exception:
            self.__monitor.close()
            raise

        self.__monitor.start()

    def __str__(self):
        return self.getDomainName() + " [Entered through: " + self.getEntryPeer().getConnectStr() + "]"

    def disconnect(self):
        self.__monitor.close()

    def getUser(self):
        return self.__user

    def getPassword(self):
        return self.__password

    def getDomainName(self):
        return self.__domainName

    def getPeer(self, agentId):
        return self.__peers.get(agentId)

    def getPeers(self):
        return self.__peers.itervalues()

    def getEntryPeer(self):
        return self.__entryPeer

    def getDatabase(self, name):
        return self.__databases.get(name)

    def getDatabases(self):
        return self.__databases.itervalues()

    def getDatabaseCount(self):
        return len(self.__databases)

    def shutdown(self, graceful=True):
        for (dbName, db) in self.__databases.items():
            db.shutdown(graceful)

    def messageReceived(self, root):
        if root.tag == "Event":
            eventType = root.get("Type")
            if eventType == "NewBroker":
                self.__peerJoined(Peer.fromMessage(self, root.find("Broker")))
            elif eventType == "BrokerExit":
                self.__peerLeft(Peer.fromMessage(self, root.find("Broker")))
            elif eventType == "StatusChanged":
                status = root.get("Status")

                processElement = root.find("Process")
                db = self.__databases[processElement.get("Database")]
                process = Process.fromMessage(db, processElement)

                self.__processStatusChanged(process, status)
            elif eventType == "ProcessFailed":
                peer = Peer.fromMessage(self, root.find("Broker"))
                peer = self.getPeer(peer.getId())

                reason = root.get("Reason")
                startId = root.get("StartId")

                self.__processFailed(peer, startId, reason)
            elif eventType == "NewProcess" or eventType == "ProcessExit":
                processElement = root.find("Process")
                dbName = processElement.get("Database")

                if dbName not in self.__databases:
                    self.__databases[dbName] = Database(self, dbName)
                    if self.__listener:
                        try:
                            self.__listener.databaseJoined(self.__databases[dbName])
                        except:
                            pass

                if eventType == "NewProcess":
                    startId = processElement.get("StartId")
                    self.__processJoined(Process.fromMessage(self.__databases[dbName], processElement), startId)
                else:
                    self.__processLeft(Process.fromMessage(self.__databases[dbName], processElement))

    def closed(self):
        if self.__listener:
            try:
                self.__listener.closed()
            except:
                pass

    # NOTE: this is the status provided on initial broker-connection, and not
    # per-process status updates
    def __handleStatus(self, message):
        root = ElementTree.fromstring(message)
        if root.tag != "Status":
            raise Exception("Expected status message; got " + root.tag)

        self.__domainName = root.get("Domain")

        self.__entryPeer = Peer(
            self,
            self.__session.getAddress(),
            root.get("AgentId"),
            (root.get("Role") == "Broker"),
            self.__session.getPort(),
            root.get("Hostname"),
            root.get("Version"),
        )
        self.__peerJoined(self.__entryPeer)

        for child in list(root):
            if child.tag == "Broker":
                self.__peerJoined(Peer.fromMessage(self, child))

        for child in list(root):
            if child.tag == "Database":
                name = child.get("Name")
                if self.__listener:
                    try:
                        self.__listener.databaseJoined(self.__databases[name])
                    except:
                        pass

                for processElement in list(child):
                    if processElement.tag == "Process":
                        if name not in self.__databases:
                            self.__databases[name] = Database(self, name)
                        self.__processJoined(Process.fromMessage(self.__databases[name], processElement), None)

    def __peerJoined(self, peer):
        self.__peers[peer.getId()] = peer
        if self.__listener:
            try:
                self.__listener.peerJoined(peer)
            except:
                pass

    def __peerLeft(self, peer):
        del self.__peers[peer.getId()]
        if self.__listener:
            try:
                self.__listener.peerLeft(peer)
            except:
                pass

    def __processJoined(self, process, startId):
        process.getDatabase()._addProcess(process)
        process.getPeer()._notifyStartId(startId, process)
        if self.__listener:
            try:
                self.__listener.processJoined(process)
            except:
                pass

    def __processLeft(self, process):
        database = process.getDatabase()
        database._removeProcess(process)
        process.getPeer()._removeProcess(process)
        if self.__listener:
            try:
                self.__listener.processLeft(process)
            except:
                pass

        if database.getProcessCount() == 0:
            del self.__databases[database.getName()]
            if self.__listener:
                try:
                    self.__listener.databaseLeft(database)
                except:
                    pass

    def __processFailed(self, peer, startId, reason):
        peer._notifyStartId(startId, reason)
        if self.__listener:
            try:
                self.__listener.processFailed(peer, reason)
            except:
                pass

    def __processStatusChanged(self, process, status):
        process._setStatus(status)
        if self.__listener:
            try:
                self.__listener.processStatusChanged(process, status)
            except:
                pass

    # an initial verison only to support the shutdown routine that doesn't
    # need to watch for return messages ... right now this module is only
    # supporting the tests, which don't need the other management routines
    # at this point, so we'll flesh this out (as in the Java implementation)
    # in the second round when other utilites get updated as well
    def _sendManagementMessage(self, message, peer, process):
        root = ElementTree.fromstring(
            '<ManagementRequest AgentId="%s" ProcessId="%i"/>' % (peer.getId(), process.getPid())
        )
        root.append(message)

        self.__session.send(ElementTree.tostring(root))