class Infra(object, metaclass=Singleton):

    def __init__(self):

        try:
            '''
            if not infraType or infraType not in ['REST','SCHEDULE','DAEMON']:
                print('expectig valid infra type REST/SCHEDULE/DAMEON got {got}, exiting !!!'.format(got = infraType))
                sys.exit(-1)
            '''
            self.env = Environment()
            self.globals = Global()
            self.util = Utility()
            self.logging = Logging()

            self.configLoc = self.env.appCfgLoc
            #print(self.configLoc)
            self.bootStrapFile = os.path.join(self.configLog, self.globals.bootStrapFile)
            if not self.bootStrapFile:
                print('error: port8-infra10001, bootstrap error !!!')
                sys.exit(-1)

            self.dbConfigData = {}
            self.daemonConfifData = {}
            self.schedulerConfigData = {}
            self.restApiConfigData = {}
            self.agentConfigData = {}

            #print(self.Env._Env__initData)
            #print(self.Env._Env__EnvDetails)

            print("Loading bootstrap config....................".ljust(50),end='')
            self.__loadBootStrapConfig()
            self.__loadSchema()

            # ensuring all needed lib is available
            print("Checking all required libraries................".ljust(50),end='')
            self.__validateAllLib()

            '''
            self.Logger = \
                self.logging.buildLoggingInfra(\
                    self.loggingConfigData,\
                    self.globals.LoggerName[infraType]['LogFile'],
                    self.globals.LoggerName[infraType]['Name']
                    )
            '''
            #self.Logger.debug('this is test from Infrastructure')

            # ensure db is up and repository is abvailable
            #print("Validating database............................".ljust(50),end='')
            #self.__validateDb(infraType)
            #self.db = self.__getNewConnection()

            # loading DB schema
            # populating json schema for database
            '''
            commenting follwoing line, will revisit later to implement jsonref for db
            self.__loadDbJsonSchema()        
            '''
            #print("Loading logging config.........................".ljust(50),end='')
            #self.logger = Logging(self.loggingConfigData)
            #logger 
            print("[infra started with OS pid {pid}]".format(pid=self.getMyOsPid()))

            #self.db_dyna_sql = self.jsonSchema.get('Main').get('db_dyna_sql_call')
            #self.myModuleLogger.info ('Infrastructure started with os pid [{pid}]'.format(pid=os.getpid()))

        except Exception as err:

            exc_type, exc_value, exc_traceback = sys.exc_info()
            myErrorMessage = repr(traceback.format_exception(exc_type, exc_value, exc_traceback))

            print ('Error [{error}], terminating !!!'.format(error=myErrorMessage))
            sys.exit(-1)

    def __loadBootStrapConfig(self):

        # read bootstrap cnfig file
        try:
            self.__bootStrapData = json.load(open(self.bootStrapFile))

            if not self.__bootStrapData:
                print("Empty bootstrap data, terminating !!!")
                sys.exit(-1) 

            # validating if all modules config data is available
            myMissingModule = self.util.findMissingKeyInDict(self.__bootStrapData['Main']['Modules'], list(self.__bootStrapData['Main']['Modules'].keys()))
            if myMissingModule:
                print('Missing config information for module {0}'.format(myMissingModule))
                sys.exit(-1)

            #extracting module config information
            if self.env.environment not in self.__bootStrapData['Main']['Modules']['DB']['REPOSITORY']:
                print('[Error]\n     unable to find repository information for environment >> {env}'.format(env = self.env.environment))
                sys.exit(-1)

            if not self.env.environment in self.__bootStrapData['Main']['Modules']['DB']['REPOSITORY']:
                print('invalid environment >>> {env}'.format(env=self.env.Environment))
                sys.exit(-1)

            self.repConfigData = self.__bootStrapData['Main']['Modules']['DB']['REPOSITORY'][self.env.environment]
            self.dbConfigData = {
                'user' : self.repConfigData['User'], 
                'password' : self.repConfigData['enc'], 
                'host' : self.repConfigData['Host'], 
                'port' : self.repConfigData['Port'],
                'database' : self.repConfigData['Name']
            }

            self.schedulerConfigData = self.__bootStrapData['Main']['Modules']['Scheduler']
            self.loggingConfigData = self.__bootStrapData['Main']['Modules']['Logging']
            self.restApiConfigData = self.__bootStrapData['Main']['Modules']['RestAPI']
            self.daemonConfigData  = self.__bootStrapData['Main']['Modules']['Daemon']
            self.jsonSchemaConfigData  = self.__bootStrapData['Main']['JsonSchema']

            if (not self.repConfigData):
                print('Repository DB Configuration is empty')
                sys.exit(-1)

            if (not self.schedulerConfigData):
                print('Scheduler Configuration is empty')
                sys.exit(-1)

            if (not self.loggingConfigData):
                print('Loggine Configuration is empty')
                sys.exit(-1)

            if (not self.restApiConfigData):
                print('RestApi Configuration is empty')
                sys.exit(-1)

            if (not self.restApiConfigData):
                print('Daemon Configuration is empty')
                sys.exit(-1)

            if (not self.jsonSchemaConfigData):
                print('Json Schema Configuration is empty')
                sys.exit(-1)

            print("[OK]")

        except Exception as err:
            myErrorMessage = sys.exc_info()[1:],traceback.format_exc(limit=2)            
            #myErrorMessage = self.Utility.extractError()
            print(myErrorMessage)
            #print("Error [{err}] loading bootstrap config data".format(err=err))
            sys.exit(-1)
    
    def __loadSchema(self):
        
        # load json schema data and resolve the reference if used, this will be needed to validate user data
        #print(self.configLoc)
        configFile = self.util.buildFileWPath(self.configLoc, self.jsonSchemaConfigData['ConfigFile'])
        if not self.util.isFileExist(configFile):
            print('Json Schema Configuration file {file} is missing !!!'.format(file=os.path.join(self.configLoc,self.jsonSchemaConfigData['ConfigFile'])))
            sys.exit(-1)
        
        #loading json schema file and resolving references if used in schema
        try:
            self.jsonSchema = JsonRef.replace_refs(json.load(open(configFile)))
            #print(self.jsonSchema)
        except Exception as err:
            myErrorMessage = sys.exc_info()[1:],traceback.format_exc(limit=2)            
            print (myErrorMessage)
            sys.exit(-1)

    def __validateAllLib(self):

        # Ensuring all required library as specified in bootStrap.json is installed
        try:
            for lib in self.__bootStrapData['Main']['libraries']:
                if not self.util.isPackageInstalled(lib):
                    #self.myModuleLogger.error('Lib {frmtLib} is not installed, Pls install it using <pip install {frmtLib}>'.format(frmtLib=lib))
                    print("[missing library {frmtLib}]".format(frmtLib=lib))
                    sys.exit(-1)

            print("[OK]")

        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            myErrorMessage = repr(traceback.format_exception(exc_type, exc_value, exc_traceback))

            print('[Failed {err}]'.format(err=myErrorMessage))      
            sys.exit(-1)

    def isValidBootStrapData(self):
        if self.__bootStrapData:
            return True
        else:
            return False

    def isValidLogger(self):
        if self.myModuleLogger:
            return True
        else:
            return False

    def getBootStrapFile(self):
        
        #print(self.env._Environment__bootStrapFileKey)
        #print (self.env._Environment__initData)
        return self.env._Environment__initData[self.env._Environment__bootStrapFileKey]
        #mybootStrapFile = os.getEnv[self.Env._Environment__bootStrapKey]

    def getAppName(self):
        return os.Environ['APP_NAME']

    def getMyOsPid(self):
        # returns current OS pid
        return os.getpid()

    def getInfraLogger(self, infraArg):
        if infraArg == 'Scheduler':
            return self.SchedLogger
        elif infraArg == 'Daemon':
            return self.DaemonLogger
        elif infraArg == 'Rest':
            return self.RestLogger

    def isModuleInstalled(self,  argLib):

        # returns existence of a library passed as an argument

        try:
            __import__('imp').find_module(argLib)
            return True
        except ImportError:
            #print('Missing library {lib}'.format(lib=argLib))
            return False

    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #                                  method for DB
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    

    def __validateMySqlDB(self):

        self.dbLib = importlib.import_module('mysql.connector')

        # validate the db config file
        try:
            # connecting to database to ensure db is up
            db = self.dbLib.connect(host = self.dbConfigData['host'], port = self.dbConfigData['port'], user = self.dbConfigData['user'], password = self.util.decrypt(self.repConfigData['key'], self.dbConfigData['password']), database = self.dbConfigData['database'])

            # connection is successful, closing the connection
            db.close()
            # connection is successful
        except self.dbLib.Error as err:
            if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
                print("something is wrong with your user name or password, exiting !!!")
                sys.exit(-1)
            elif err.errno == errorcode.ER_BAD_DB_ERROR:
                print("Database does not exist, exiting !!!")
                sys.exit(-1)
            else:
                print(err)
        '''
        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            myErrorMessage = repr(traceback.format_exception(exc_type, exc_value, exc_traceback))

            print('[Failed {err}]'.format(err=myErrorMessage))      
            sys.exit(-1)
        '''

    def __validateDb(self,infraType):
        #print(self.repConfigData)
        if infraType == 'REST':
            if self.repConfigData['Vendor'] == "mysql" :
                self.__validateMySqlDB()
            else:
                print('unsuported database for repository')
                sys.exit(-1)
        else:
            pass
        print("[OK]")

    def __loadDbJsonSchema(self):
        #self.dbSchema = self.jsonSchema.get('Main').get('db_schema').get(self.__bootStrapData['Main']['Modules']['DB']['REPOSITORY'])
        
        self.dbSchema = self.jsonSchema.get('Main').get('db_schema').get(self.__bootStrapData['Main']['Modules']['DB']['REPOSITORY'][self.env.environment])

    def __getNewConnection(self):
        try:
            #print('db config',self.dbConfigData)
            db = self.dbLib.connect(host = self.dbConfigData['host'], port = self.dbConfigData['port'], user = self.dbConfigData['user'], password = self.util.decrypt(self.repConfigData['key'], self.dbConfigData['password']), database = self.dbConfigData['database'])
            #dbCursor = db.cursor(dictionary=True, buffered=True)
            #dbCursor = db.cursor(buffered=True)
            return db
        except Exception as err:
            self.logger.critical('Error obtaining db connection using {}'.format(self.dbConfigData))
            raise err

    def __closeConnection(self, conn):
        if conn:
            conn.close()

    def isConnectionOpen(self, conn):
        try:
            dbCur = conn.cursor()
            dbCur.execute('select now()')
            return True
        except Exception as err:
            return False
Beispiel #2
0
class Environment(object, metaclass=Singleton):

    def __init__(self):

        self.Global = Global()
        self.util = Utility()

        if not self.util.isEnvSet('ENVIRONMENT'):
            raise ValueError('ENVIORNMENT key is not set')

        if not self.util.isEnvSet('ENVIRONMENT'):
            print('environment is not set, exiting !!!')
            sys.exit(-1)

        self.environment = self.util.getEnv('ENVIRONMENT')

        print('setting environment >> {env}'.format(env=self.environment))
        # need to set environments specific variables dev, test and production
        self.lPad = 50
        self.rPad = 1
        self.__initFile = self.Global.InitFile
        self.__initKeys = self.Global.InitKeys
        self.__bootStrapKey = self.Global.BootStrapKey
        self.__bootStrapFileKey = self.Global.BootStrapFileKey
        self.__logLocKey = self.Global.LogLocKey
        self.__envDetails={}
        self.invalidAppDir = list()
        self.invalidAppFile = list()


        if not self.util.isEnvSet('PYTHONPATH'):
            print('missing PYTHONPATH environment variable, terminating !!!')
            sys.exit(-1)
        else:
            self.__envDetails.update({'PYTHONPATH'  : self.util.getEnv('PYTHONPATH')})
        #fi

        print('Current OS : [{os}]'.format(os=self.util.getUname()))
        print ("Initializing ...")

        # searching init file
        # 1. search in current directory, 2. search in pythonpath, 3. search in APP_CONFIG dir

        print('searching init file')
        # searching file in current dir
        if not self.util.isFileExist(self.__initFile):
            # searching file in PYTHONPATH
            if not(self.util.isFileExist(self.util.buildFileWPath(self.__envDetails['PYTHONPATH'],self.__initFile))):
                if self.util.isEnvSet('APP_CONFIG'):
                    # searching file in APP_CONFIG dir
                    if not(self.util.isFileExist(self.util.buildFileWPath(self.util.getEnv('APP_CONFIG'),self.__initFile))):
                        print("Bootstrap error; missing init.json, terminating !!!")
                        sys.exit(-1)
                    else:
                        self.__initFile = self.util.buildFileWPath(self.util.getEnv('APP_CONFIG'),self.__initFile)
                        print('init file [{file}] found'.format(file=self.__initFile))
                else:
                    print("Bootstrap error; Exhasuted searching couldn\'t find init file, terminating !!!")
                    sys.exit(-1)
            else:
                self.__initFile = self.util.buildFileWPath(self.__envDetails['PYTHONPATH'],self.__initFile)
                print('init file [{file}] found'.format(file=self.__initFile))

        # Loading init file
        self.__initData = json.load(open(self.__initFile))
        if not self.__initData:
            print('Bootstra error, could not load init file >>> {file}'.format(file = self.__initFile))
            sys.exit(-1)

        # ensure all required key found in int file
        if not all (key in self.__initData.keys() for key in self.__initKeys):
            print("Missing required keys in init file, terminating !!!")
            sys.exit(-1)

        # Set all environment variable if not set
        if not all (self.util.isEnvSet(env) for env in self.__envDetails.keys()):
            print("app environment key is not set, building ...")
            #print("Setting environment...........................".ljust(self.lPad),end='')
            # app home
            self.setInitEnv()

        # validating required app directories/files >>> allAppDir = [dir[key] for index, key in enumerate(self.__initData)]
        #print(self.__initData)
        self.validateAppDir(self.__initData['VALIDATE_DIR_LIST'])
        self.validateAppFile(self.__initData['VALIDATE_FILE_LIST'])
        self.validateLogDir(self.__initData['APP_LOG']) # validating app log, create if we are missing

        self.appCfgLoc = self.__initData['APP_CONFIG']
        self.appLogLoc = self.__initData['APP_LOG']

    def setInitEnv(self):
        # set all missing env key
        for envKey in self.__envDetails:
            if not self.util.isEnvSet(envKey):
                self.util.setEnv(envKey,self.__envDetails[envKey])
            #fi
        #end for

    def validateAppDir(self, dirList):
        '''
        Description: Validate all system dir stored in init.json, if dir name not found will exit
        '''

        isMissing = False
        missingAppDir = list()
        for dirKeyVal in (dirList):
            # we are expecting dict stored in list, will check the 1st key from dict to get the dir key name 
            if not self.util.isDirExist(dirKeyVal[next(iter(dirKeyVal))]):
                missingAppDir.append(dirKeyVal)
                if not isMissing: isMissing = True 

        if isMissing:
            print('system dir is missing >>> {missing}'.format(missing = str(missingAppDir)))
            sys.exit(-1)

    def validateAppFile(self, fileList):
        '''
        Description: Validate all system file stored in init.json, if file name not found will exit
        '''

        isMissing = False
        missingAppFile = list()        
        for fileKeyVal in fileList:
            # we are expecting dict stored in list, will check the 1st key from dict to get the dir key name
            #print(fileKeyVal)
            if not self.util.isFileExist(fileKeyVal[next(iter(fileKeyVal))]):
                missingAppFile.append(fileKeyVal)
                if not isMissing: isMissing = True 

        if isMissing:
            print('system file(s) is missing >>> {missing}'.format(missing = str(missingAppFile)))
            sys.exit(-1)

    def validateLogDir(self, logDir):
        #if not os.path.isdir(os.environ[self.__logLocKey]):
        if not self.util.isDirExist(logDir):
            print('creating app log dir >>> {log}'.format(log = logDir))
            self.util.makeDir(self.util.getEnv(self.logDir))

    '''
    def getEnv(self,argEnvName):
        return os.getenv(argEnvName)

    def setEnv(self,argEnvName, argEnvVal):
        try:
            os.environ[argEnvName] = argEnvVal
        except Exception as err:
            sys.exit(-1)
    def isEnvSet(self,argEnvName):
        if self.util.getEnv(argEnvName):
            return True
        else:
            return False
        #fi
    '''

    #def getConfigLocation(self):
    #    #print(os.getenv(''.join([self.util.getEnv('APP_NAME'),'_CONFIG'])))
    #    return self.util.getEnv('APP_CONFIG')

    #def getLogLocation(self):
    #    return self.util.getEnv(self.Global.LogLocKey)

    #end getLogLocation
    '''