def __init__(self, owners: list, balance: float, administration): if owners: self.owners = owners else: raise TypeError( 'Expected list of Customer object(s) in self.owners, but got empty list []' ) for owner in self.owners: owner.bank_accounts.append(self) self.interest = None self.balance = balance self.minimum_bal = 30 self.overdraft_fee = 5 self.max_owner_qty = 2 self.administration = administration self.administration.add_account( self) # add this account to Administration's list of accounts # vv I need to change this! vv self.account_number = str( randint(10000000000, 99999999999)) # generates random number as account number self.history = {'Deposits': [], 'Withdrawals': [], 'Fees': []} self.doc_manager = DocManager(self, 'BankStatement.txt', 'BankNotices.txt')
def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, doc_manager=None, auth_username=None, nodes_discovery=True): file = inspect.getfile(inspect.currentframe()) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(file)[0])) if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() #Is cluster discovery enabled self.nodes_discovery = nodes_discovery try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = "MongoC`onnector: Can't find OplogProgress file!" logging.critical(info_str) self.doc_manager.stop() self.can_run = False
class Connector(threading.Thread): """Checks the cluster for shards to tail. """ def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, doc_manager=None, auth_username=None, nodes_discovery=True): file = inspect.getfile(inspect.currentframe()) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(file)[0])) if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() #Is cluster discovery enabled self.nodes_discovery = nodes_discovery try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = "MongoC`onnector: Can't find OplogProgress file!" logging.critical(info_str) self.doc_manager.stop() self.can_run = False def join(self): """ Joins thread, stops it from running """ self.can_run = False self.doc_manager.stop() threading.Thread.join(self) def write_oplog_progress(self): """ Writes oplog progress to file provided by user """ if self.oplog_checkpoint is None: return None # write to temp file backup_file = self.oplog_checkpoint + '.backup' os.rename(self.oplog_checkpoint, backup_file) # for each of the threads write to file with open(self.oplog_checkpoint, 'w') as dest: with self.oplog_progress as oplog_prog: oplog_dict = oplog_prog.get_dict() for oplog, ts in oplog_dict.items(): oplog_str = str(oplog) timestamp = util.bson_ts_to_long(ts) json_str = json.dumps([oplog_str, timestamp]) try: dest.write(json_str) except IOError: # Basically wipe the file, copy from backup dest.truncate() with open(backup_file, 'r') as backup: shutil.copyfile(backup, dest) break os.remove(self.oplog_checkpoint + '.backup') def read_oplog_progress(self): """Reads oplog progress from file provided by user. This method is only called once before any threads are spanwed. """ if self.oplog_checkpoint is None: return None # Check for empty file try: if os.stat(self.oplog_checkpoint).st_size == 0: logging.info("MongoConnector: Empty oplog progress file.") return None except OSError: return None source = open(self.oplog_checkpoint, 'r') try: data = json.load(source) except ValueError: # empty file err_msg = "MongoConnector: Can't read oplog progress file." reason = "It may be empty or corrupt." logging.info("%s %s" % (err_msg, reason)) source.close() return None source.close() count = 0 oplog_dict = self.oplog_progress.get_dict() for count in range(0, len(data), 2): oplog_str = data[count] ts = data[count + 1] oplog_dict[oplog_str] = util.long_to_bson_ts(ts) #stored as bson_ts def run(self): """Discovers the mongo cluster (unless run with --no-discover option) and creates a thread for each primary. """ main_conn = pymongo.Connection(self.address) self.read_oplog_progress() conn_type = None try: main_conn.admin.command("isdbgrid") except pymongo.errors.OperationFailure: conn_type = "REPLSET" if not self.nodes_discovery: # don't care about connection type, just use gived address as is oplog_coll = main_conn['local']['oplog.rs'] address = self.address oplog = oplog_manager.OplogThread(main_conn, address, oplog_coll, False, self.doc_manager, self.oplog_progress, self.ns_set, self.auth_key, self.auth_username, repl_set='') self.shard_set[0] = oplog logging.info('MongoConnector: Starting connection thread %s' % main_conn) oplog.start() while self.can_run: if not self.shard_set[0].running: err_msg = "MongoConnector: OplogThread" set = str(self.shard_set[0]) effect = "unexpectedly stopped! Shutting down." logging.error("%s %s %s" % (err_msg, set, effect)) self.oplog_thread_join() self.doc_manager.stop() return self.write_oplog_progress() time.sleep(1) elif conn_type == "REPLSET": #non sharded configuration oplog_coll = main_conn['local']['oplog.rs'] prim_admin = main_conn.admin repl_set = prim_admin.command("replSetGetStatus")['set'] host = main_conn.host port = main_conn.port address = host + ":" + str(port) oplog = oplog_manager.OplogThread(main_conn, address, oplog_coll, False, self.doc_manager, self.oplog_progress, self.ns_set, self.auth_key, self.auth_username, repl_set=repl_set) self.shard_set[0] = oplog logging.info('MongoConnector: Starting connection thread %s' % main_conn) oplog.start() while self.can_run: if not self.shard_set[0].running: err_msg = "MongoConnector: OplogThread" set = str(self.shard_set[0]) effect = "unexpectedly stopped! Shutting down." logging.error("%s %s %s" % (err_msg, set, effect)) self.oplog_thread_join() self.doc_manager.stop() return self.write_oplog_progress() time.sleep(1) else: # sharded cluster while self.can_run is True: shard_coll = main_conn['config']['shards'] shard_cursor = shard_coll.find() for shard_doc in shard_cursor: shard_id = shard_doc['_id'] if shard_id in self.shard_set: if not self.shard_set[shard_id].running: err_msg = "MongoConnector: OplogThread" set = str(self.shard_set[shard_id]) effect = "unexpectedly stopped! Shutting down" logging.error("%s %s %s" % (err_msg, set, effect)) self.oplog_thread_join() self.doc_manager.stop() return self.write_oplog_progress() time.sleep(1) continue try: repl_set, hosts = shard_doc['host'].split('/') except ValueError: cause = "The system only uses replica sets!" logging.error("MongoConnector: %s", cause) self.oplog_thread_join() self.doc_manager.stop() return shard_conn = pymongo.Connection(hosts, replicaset=repl_set) oplog_coll = shard_conn['local']['oplog.rs'] oplog = oplog_manager.OplogThread(shard_conn, self.address, oplog_coll, True, self.doc_manager, self.oplog_progress, self.ns_set, self.auth_key, self.auth_username) self.shard_set[shard_id] = oplog msg = "Starting connection thread" logging.info("MongoConnector: %s %s" % (msg, shard_conn)) oplog.start() self.oplog_thread_join() def oplog_thread_join(self): """Stops all the OplogThreads """ logging.info('MongoConnector: Stopping all OplogThreads') for thread in self.shard_set.values(): thread.join()
def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, doc_manager=None, auth_username=None): file = inspect.getfile(inspect.currentframe()) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(file)[0])) if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = "MongoC`onnector: Can't find OplogProgress file!" logging.critical(info_str) self.doc_manager.stop() self.can_run = False
class Connector(threading.Thread): """Checks the cluster for shards to tail. """ def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, doc_manager=None, auth_username=None): file = inspect.getfile(inspect.currentframe()) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(file)[0])) if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = "MongoC`onnector: Can't find OplogProgress file!" logging.critical(info_str) self.doc_manager.stop() self.can_run = False def join(self): """ Joins thread, stops it from running """ self.can_run = False self.doc_manager.stop() threading.Thread.join(self) def write_oplog_progress(self): """ Writes oplog progress to file provided by user """ if self.oplog_checkpoint is None: return None # write to temp file backup_file = self.oplog_checkpoint + '.backup' os.rename(self.oplog_checkpoint, backup_file) # for each of the threads write to file with open(self.oplog_checkpoint, 'w') as dest: with self.oplog_progress as oplog_prog: oplog_dict = oplog_prog.get_dict() for oplog, ts in oplog_dict.items(): oplog_str = str(oplog) timestamp = util.bson_ts_to_long(ts) json_str = json.dumps([oplog_str, timestamp]) try: dest.write(json_str) except IOError: # Basically wipe the file, copy from backup dest.truncate() with open(backup_file, 'r') as backup: shutil.copyfile(backup, dest) break os.remove(self.oplog_checkpoint + '.backup') def read_oplog_progress(self): """Reads oplog progress from file provided by user. This method is only called once before any threads are spanwed. """ if self.oplog_checkpoint is None: return None # Check for empty file try: if os.stat(self.oplog_checkpoint).st_size == 0: logging.info("MongoConnector: Empty oplog progress file.") return None except OSError: return None source = open(self.oplog_checkpoint, 'r') try: data = json.load(source) except ValueError: # empty file err_msg = "MongoConnector: Can't read oplog progress file." reason = "It may be empty or corrupt." logging.info("%s %s" % (err_msg, reason)) source.close() return None source.close() count = 0 oplog_dict = self.oplog_progress.get_dict() for count in range(0, len(data), 2): oplog_str = data[count] ts = data[count + 1] oplog_dict[oplog_str] = util.long_to_bson_ts(ts) #stored as bson_ts def run(self): """Discovers the mongo cluster and creates a thread for each primary. """ main_conn = pymongo.Connection(self.address) self.read_oplog_progress() conn_type = None try: main_conn.admin.command("isdbgrid") except pymongo.errors.OperationFailure: conn_type = "REPLSET" if conn_type == "REPLSET": #non sharded configuration oplog_coll = main_conn['local']['oplog.rs'] prim_admin = main_conn.admin repl_set = prim_admin.command("replSetGetStatus")['set'] host = main_conn.host port = main_conn.port address = host + ":" + str(port) oplog = oplog_manager.OplogThread(main_conn, address, oplog_coll, False, self.doc_manager, self.oplog_progress, self.ns_set, self.auth_key, self.auth_username, repl_set=repl_set) self.shard_set[0] = oplog logging.info('MongoConnector: Starting connection thread %s' % main_conn) oplog.start() while self.can_run: if not self.shard_set[0].running: err_msg = "MongoConnector: OplogThread" set = str(self.shard_set[0]) effect = "unexpectedly stopped! Shutting down." logging.error("%s %s %s" % (err_msg, set, effect)) self.oplog_thread_join() self.doc_manager.stop() return self.write_oplog_progress() time.sleep(1) else: # sharded cluster while self.can_run is True: shard_coll = main_conn['config']['shards'] shard_cursor = shard_coll.find() for shard_doc in shard_cursor: shard_id = shard_doc['_id'] if shard_id in self.shard_set: if not self.shard_set[shard_id].running: err_msg = "MongoConnector: OplogThread" set = str(self.shard_set[shard_id]) effect = "unexpectedly stopped! Shutting down" logging.error("%s %s %s" % (err_msg, set, effect)) self.oplog_thread_join() self.doc_manager.stop() return self.write_oplog_progress() time.sleep(1) continue try: repl_set, hosts = shard_doc['host'].split('/') except ValueError: cause = "The system only uses replica sets!" logging.error("MongoConnector: %s", cause) self.oplog_thread_join() self.doc_manager.stop() return shard_conn = pymongo.Connection(hosts, replicaset=repl_set) oplog_coll = shard_conn['local']['oplog.rs'] oplog = oplog_manager.OplogThread( shard_conn, self.address, oplog_coll, True, self.doc_manager, self.oplog_progress, self.ns_set, self.auth_key, self.auth_username) self.shard_set[shard_id] = oplog msg = "Starting connection thread" logging.info("MongoConnector: %s %s" % (msg, shard_conn)) oplog.start() self.oplog_thread_join() def oplog_thread_join(self): """Stops all the OplogThreads """ logging.info('MongoConnector: Stopping all OplogThreads') for thread in self.shard_set.values(): thread.join()
def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, doc_manager=None, auth_username=None): if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = ("MongoConnector: Can't find %s, " "attempting to create an empty progress log" % self.oplog_checkpoint) logging.info(info_str) try: # Create oplog progress file open(self.oplog_checkpoint, "w").close() except IOError as e: logging.critical("MongoConnector: Could not " "create a progress log: %s" % str(e)) sys.exit(1) else: if (not os.access(self.oplog_checkpoint, os.W_OK) and not os.access(self.oplog_checkpoint, os.R_OK )): logging.critical("Invalid permissions on %s! Exiting" % (self.oplog_checkpoint)) sys.exit(1)
class BankAccount: def __init__(self, owners: list, balance: float, administration): if owners: self.owners = owners else: raise TypeError( 'Expected list of Customer object(s) in self.owners, but got empty list []' ) for owner in self.owners: owner.bank_accounts.append(self) self.interest = None self.balance = balance self.minimum_bal = 30 self.overdraft_fee = 5 self.max_owner_qty = 2 self.administration = administration self.administration.add_account( self) # add this account to Administration's list of accounts # vv I need to change this! vv self.account_number = str( randint(10000000000, 99999999999)) # generates random number as account number self.history = {'Deposits': [], 'Withdrawals': [], 'Fees': []} self.doc_manager = DocManager(self, 'BankStatement.txt', 'BankNotices.txt') def __repr__(self): owner_names = [owner.name for owner in self.owners] return 'Account: {};\tOwner{}: {}'.format( self.account_number, 's' if len(self.owners) > 1 else '', ', '.join([name.split()[0] for name in owner_names]) if self.owners else 'None') def add_customer(self, customer): """ Adds a customer to associated object lists. Writes a notice to the user. :param customer: Customer object :return: None """ if len(self.owners) < self.max_owner_qty: self.owners.append(customer) customer.bank_accounts.append(self) self.doc_manager.add_customer_notice(customer, dt.today()) else: raise TypeError( 'Maximum number of customers reached. Cannot add additional customers to account.' ) def remove_customer(self, customer): """ Removes a customer from associated object lists. Writes a notice to the user. :param customer: Customer object :return: None """ if customer in self.owners and len(self.owners) > 1: self.owners.remove(customer) customer.bank_accounts.remove(self) self.doc_manager.remove_customer_notice(customer, dt.today()) elif customer in self.owners and len(self.owners) == 1: customer.bank_accounts.remove(self) self.owners.remove(customer) self.doc_manager.no_owner_notice(dt.today()) else: raise TypeError( '{} was not an owner of this account'.format(customer)) def charge_overdraft_fee(self): """ Charges an overdraft fee to the account. Writes a notice to the user. :return: None """ self.balance -= self.overdraft_fee self.doc_manager.overdraft_notice(dt.today()) def deposit(self, amount: float): """ Adds a given amount to the bank account. Add transaction to account's history. Notify the user of transaction. :param amount: float dollar amount :return: None """ if amount > 0: self.balance += amount timestamp = dt.today() self.history['Deposits'].append({ 'Date': timestamp, 'Amount': amount, 'Balance': self.balance }) self.doc_manager.transaction_notice(trans_type='deposit', amount=amount, timestamp=timestamp) else: raise ValueError('Deposit amount must be positive')
def __init__(self, address, oplog_checkpoint, target_url, ns_set, u_key, auth_key, no_dump, batch_size, doc_manager=None, auth_username=None): if doc_manager is not None: doc_manager = imp.load_source('DocManager', doc_manager) else: from doc_manager import DocManager time.sleep(1) super(Connector, self).__init__() #can_run is set to false when we join the thread self.can_run = True #The name of the file that stores the progress of the OplogThreads self.oplog_checkpoint = oplog_checkpoint #main address - either mongos for sharded setups or a primary otherwise self.address = address #The URL of the target system self.target_url = target_url #The set of relevant namespaces to consider self.ns_set = ns_set #The key that is a unique document identifier for the target system. #Not necessarily the mongo unique key. self.u_key = u_key #Password for authentication self.auth_key = auth_key #Username for authentication self.auth_username = auth_username #The set of OplogThreads created self.shard_set = {} #Boolean chooses whether to dump the entire collection if no timestamp # is present in the config file self._no_dump = no_dump #Num entries to process before updating config file with current pos self._batch_size = batch_size #Dict of OplogThread/timestamp pairs to record progress self.oplog_progress = LockingDict() try: if target_url is None: if doc_manager is None: # imported using from... import self.doc_manager = DocManager(unique_key=u_key) else: # imported using load source self.doc_manager = doc_manager.DocManager(unique_key=u_key) else: if doc_manager is None: self.doc_manager = DocManager(self.target_url, unique_key=u_key) else: self.doc_manager = doc_manager.DocManager(self.target_url, unique_key=u_key) except SystemError: logging.critical("MongoConnector: Bad target system URL!") self.can_run = False return if self.oplog_checkpoint is not None: if not os.path.exists(self.oplog_checkpoint): info_str = "MongoConnector: Can't find OplogProgress file!" logging.critical(info_str) self.doc_manager.stop() self.can_run = False else: if (not os.access(self.oplog_checkpoint, os.W_OK) and not os.access(self.oplog_checkpoint, os.R_OK )): logging.critical("Invalid permissions on %s! Exiting" % (self.oplog_checkpoint)) sys.exit(1)