class MysqlUtil(object, metaclass=Singleton): def __init__(self, logger=None): self.util = Utility() self.globals = Global() #self.env = Environment() self.dbResponse = self.util.getACopy( self.globals.Template['DBResponse']) self.infra = RestInfra() self.encryptKey = self.infra._Infra__bootStrapData['Main']['Key'] if logger: self.logger = logger else: print('no logger is available, can not store logging information') self.logger = None # select @@port; # show variables where variable_name = 'port' # select user(); # insert json in mysql # insert into temp values(json_array(json_object('id',1001,'when','2015-01-01 10:00:00','score',35), json_object('id',1002,'when','2015-02-01 10:00:00','score',45)) ); def makeConnection(self, host, port, username, encryptPass, dbName, tzone=None): try: #print('pass',self.util.decrypt(self.env.encryptPass)) conn = connect(host=host, port=port, user=username, password=self.util.decrypt(self.encryptKey, encryptPass), database=dbName) #print(conn) # we need to set the timezone as requested for this connection if tzone: conn.time_zone = '+00:00' return conn except errors.Error as error: #return self.util.buildDBResponse(self.globals.Error, None, None, error) raise except Exception as error: raise #return self.util.buildDBResponse(self.globals.Error, None, None, error) def getRepDBConnection(self): try: #print('pass',self.util.decrypt(self.env.encryptPass)) conn = self.makeConnection(\ self.infra.dbConfigData['host'], \ self.infra.dbConfigData['port'], \ self.infra.dbConfigData['user'], \ self.infra.dbConfigData['password'], \ self.infra.dbConfigData['database']) return conn except Exception as error: raise #return self.util.buildDBResponse(self.globals.Error, None, None, error) def execSelectSql(self, **args): ''' Description: Execute Select statement Arguments: Key word arguments Conn : Connection handler SqlText : Sql to be executed SqlArgs : Arguments need to be passed to sql (optional), default = None (SqlArgs should be in dict) SqlOutput : Sqloutput Dict/Touple (optional), default = Touple Usage : execSelectSql(<connection>, <sql>, <sql args (optional)>, <sql output Dict/Touple (optional)> ) Return : Array internal --> #mySqlArgs = ','.join(list(map(lambda x: '%s', args))) ''' try: myRequiredArgs = ['Conn', 'SqlText'] #Validating arguments myArgValResult = self.util.valArguments(myRequiredArgs, args) if myArgValResult['Status'] == self.globals.UnSuccess: raise InvalidArguments(myArgValResult['Message']) #extracting arguments myDBConn = args['Conn'] mySqlText = args['SqlText'] if not mySqlText.upper().startswith( ('SELECT', 'INSERT', 'UPDATE', 'DELETE')): raise InvalidArguments( 'SQL statement can be SELECT/INSERT/UPDATE/DELETE only') mySqlArgs = args['SqlArgs'] if 'SqlArgs' in args else None mySqlOutput = args[ 'SqlOutput'] if 'SqlOutput' in args else self.globals.SqlOutput[ 'Default'] if mySqlOutput not in self.globals.SqlOutput['All']: mySqlOutput = self.globals.SqlOutput['Default'] # executing sql print('Executing sql >>>', mySqlText, mySqlArgs) myDBcur = myDBConn.cursor(buffered=True) totalRows = myDBcur.execute(mySqlText, mySqlArgs) if mySqlText.upper().startswith('SELECT'): if myDBcur.with_rows: # if we got any data myTotalRows = myDBcur.rowcount #myCurDesc = myDBcur.description myAllColumns = myDBcur.column_names myRawData = myDBcur.fetchall() # build the sqloutput if mySqlOutput == self.globals.SqlOutput['Dict']: #myAllColumns = [column[0] for column in myCurDesc] myData = [ dict(zip(myAllColumns, row)) for row in myRawData ] else: myData = myRawData else: myData = None elif mySqlText.upper().startswith(('INSERT', 'UPDATE', 'DELETE')): pass myDBcur.close() return self.util.buildDBResponse(self.globals.Success, myData, myTotalRows) except errors.Error as error: #return self.util.buildDBResponse(self.globals.Error, None, None, error) raise except Exception as error: self.util.logError() raise #return self.util.buildDBResponse(self.globals.Error, None, None, error) def commitTrans(self, dbConn): try: dbConn.commit() except errors.Error as error: return self.util.buildDBResponse(self.globals.Error, None, None, error) except Exception as error: return self.util.buildDBResponse(self.globals.Error, None, None, error) def rollbackTrans(self, dbConn): try: dbConn.rollback() except errors.Error as error: return self.util.buildDBResponse(self.globals.Error, None, None, error) except Exception as error: return self.util.buildDBResponse(self.globals.Error, None, None, error) def buildMarkerForSql(self, sqlText, argList, marker): sqlArgMarker = ', '.join(list(map(lambda x: marker, args))) return sqlText % sqlArgMarker def buildDynaSql(self, colList, tableList, criteria): if colList: mySql = colList # adding tables to sql for indx, table in enumerate(tableList): if indx > 0: # found more than one table, we need to add ',' in from clause to seperate tables mySql = ''.join([mySql, ' , ', table]) else: mySql = ''.join([mySql, ' from ', table]) # adding where clause if criteria: mySql = ''.join([mySql, ' where ', criteria]) return mySql
class Factory(object, metaclass=Singleton): ''' This is Factory class, this will execute a BO process as mapped in config/FactoryMetadata.json ''' def __init__(self): #self.util = Utility.Instance() self.globals = Global() self.util = Utility() self.infra = RestInfra() self.logger = self.infra.logger #self.myClass = self.__class__.__name__ def processRequest(self, argRequestDict): ''' Description: Update key in dictDocument for a given collection, this is a private method argCollection: Collection name argDictDocument:Dict documents usage: <processRequest(argRequestDict) ''' try: self.logger.debug( "arg received [{args}]".format(args=argRequestDict)) myMainArgData = self.util.getACopy(argRequestDict) ''' Validating argumemt received ''' isValidRequest = self.util.isValidRestRequest(myMainArgData) if not (isValidRequest): raise com.port8.core.error.InvalidArguments( "Arg validation error {arg}".format(arg=myMainArgData)) else: self.logger.debug( 'validated request, its a valid request >>> {req}'.format( req=str(argRequestDict))) #fi myPageId = myMainArgData['Page'] myActionId = myMainArgData['Action'] myArguments = myMainArgData['Arguments'] myResult = self.__findBPSProcess(myPageId, myActionId) if myResult['Status'] == self.globals.Success: myBPMProcess = myResult['Data'] else: # we did not find BPM process, returing result return myResult # extracting tuple value returned from above method #myLibrary, myClass, myMethod = bpsProcessVal if myBPMProcess: self.logger.debug("found, bpm process [{bpmproc}]".format( bpmproc=myBPMProcess)) myResponse = self.__executeBPSPRocess(myBPMProcess['lib'], myBPMProcess['cls'], myBPMProcess['method'], myArguments) #myRquestStatus = self.util.getRequestStatus(self.globals.Success) else: self.logger.debug("did not find mapped bpm process") myRquestStatus = self.util.getRequestStatus(\ self.globals.UnSuccess,'Invalid Page [{page}] Action [{action}]'.format(page=myPageId, action=myActionId)) myResponse = self.util.buildResponseData( myRquestStatus, 'Error') self.logger.debug( 'myResponse data >>> {response}'.format(response=myResponse)) return myResponse except Exception as err: myRequestStatus = self.util.logError() myResponse = self.util.buildResponseData(myRequestStatus, 'Error') return myResponse def __findBPSProcess(self, argPageId, argActionId): ''' Description:This is private methd called internally in Factry class; Find BMP method call for a given request (pageid, actionid) Arguments: pageid and action id (pageid, actionid) Usage: <__findBPSProcess(<pageid>,<actionid>)> Return: BPM_CALL_JSON dict {'cls': <class>, lib : <library>, method : <mehtod>, args : <arguments needed>} ''' try: self.logger.debug("arg received [{page},{action}]".format( page=argPageId, action=argActionId)) page = [ page for page in self.infra.factoryMetadata if page['PAGE_ID'] == argPageId and page['PAGE_STATUS'] == 'ACTIVE' ] # if we found multiple page, will log the details if len(page) > 1: self.logger.ERROR( 'Expecting 1 entry per page, found {found}, Factory metadata >> {factoryData}' .format(found=len(page), factoryData=self.infra.factoryData)) myResponse = self.util.buildResponse(\ self.globals.UnSuccess, 'Metadata is corrupted (found [{cnt}] occurrance of page [{page}]'\ .format(cnt = len(page), page=argPageId)) return myResponse if len(page) == 0: # we did not find page self.logger.debug( 'did not find requested page >>> {page}'.format( page=argPageId)) myResponse = self.util.buildResponse(\ self.globals.UnSuccess, 'Missing requested page in metadata >>> {page}'.format(page=argPageId)) return myResponse # we found one page, get the 1st item from list self.logger.debug( 'found matching page [{page}] in factory metdata'.format( page=argPageId)) page = page[0] pageActions = page['ACTIONS'] if pageActions: actionIndx = [ indx for indx, val in enumerate(pageActions) if pageActions[indx]['ACTION_ID'] == argActionId ] #print("found ??? >>>",actionIndx, pageActions) if actionIndx: self.logger.debug( 'found matching action [{action}] on page [{page}] in factory metdata' .format(action=argActionId, page=argPageId)) if isinstance(actionIndx, list): actionIndx = actionIndx[0] #myBPMCallJson = self.infra.factoryMetadata[argPageId][actionIndx][argActionId] #print("found action >>>",actionIndx, pageActions, pageActions[actionIndx] ) myBPMCallJson = pageActions[actionIndx]['BPM_CALL_JSON'] self.logger.debug('BPM Json call found >>> {bpm}'.format( bpm=str(myBPMCallJson))) myResponse = self.util.buildResponse(\ self.globals.Success, self.globals.Success,myBPMCallJson) return myResponse #return myBPMCallJson else: self.logger.debug( 'action [{action}] not found for page [{page}] in factory metdata' .format(action=argActionId, page=argPageId)) myResponse = self.util.buildResponse(\ self.globals.UnSuccess, 'Missing requested action [{action}] for page >>> {page}'.format(action = argActionId, page=argPageId)) return myResponse else: myResponse = self.util.buildResponse(\ self.globals.UnSuccess, 'Empty actions for page in metadata >>> {page}'.format(page=argPageId)) return myResponse except Exception as err: #myRequestStatus = self.util.extractLogError() raise def __executeBPSPRocess(self, argLib, argCls, argMethod, arguments): ''' Description:Private method, internally called in Factory method, execute Factory bpm process Arguments: lib, class, method, arguments usage: <__executeBPSPRocess(<lib>,<cls>,<method>,<arguments>) > Return: Return results in array ''' try: self.logger.debug( "arg received [{lib},{cls},{method},{args}]".format( lib=argLib, cls=argCls, method=argMethod, args=arguments)) myModule = importlib.import_module(argLib) myClass = getattr(myModule, argCls) # if singleton, get an instance else instantiate the class if hasattr(myModule, 'Singleton') and hasattr(myClass, 'Instance'): myCallableClass = myClass.Instance() else: myCallableClass = myClass() # get the method from this class myMethod = getattr(myCallableClass, argMethod) ''' Only MainArg need to be passed ''' #myMainArg = {'MainArg':self.util.extMainArgFromReq(argReqJsonDict)} ''' need to mark that this response is external ''' #myMainArg['MainArg'].update({'ResponseMode':self.globalInstance._Global__ExternalRequest}) # execute the method if arguments: self.logger.info( "executing method with arguments >>>[{lib}.{cls}.{method} {args}]" .format(lib=argLib, cls=argCls, method=argMethod, args=arguments)) myResults = myMethod(arguments) else: self.logger.info( "executing method w/o arguments >>>[{lib}.{cls}.{method}]". format(lib=argLib, cls=argCls, method=argMethod)) myResults = myMethod() self.logger.debug('results after execution >>> {data}'.format( data=str(myResults))) return (myResults) except Exception as err: #myRequestStatus = self.util.extractLogError() #myResponse = self.util.buildResponseData(myMainArgData['ResponseMode'], myRequestStatus, 'Error') raise