#!/usr/bin/python # -*- coding: utf-8 -*- # --------------------------------------------------------------------------------------------------------- # Author : Ulrich Carmesin # Source : gitea.ucarmesin.de # --------------------------------------------------------------------------------------------------------- # managing the components # ----------------------------------------------------------------------------- """ component has to be created in relation of the application (basis.yml). Each componente could be created mostly once, but not everytime: * the same instance of a component is used in different contexts * there could be exist more instances * there could be alternatives of an instance Each kind of instance has its component-class and for each use should be an object be created. Each crated component-onject are documented in the parameter-file. """ import utils.config_tool import utils.conn_tool import basic.program import basic.message import basic.component import importlib import copy import basic.constants as B import utils.data_const as D comps = {} PARAM_NOSUBNODE = [B.SUBJECT_ARTS, "components", "instance"] DEFAULT_INST_CNT = 1 DEFAULT_INST_SGL = "y" def getInstanceAttributes(conf): """ the attributes for instancing the component are set from configuration or from default :param conf: :return: a complete set of these attributes """ out = { B.ATTR_INST_CNT: DEFAULT_INST_CNT, B.ATTR_INST_SGL: DEFAULT_INST_SGL } if B.SUBJECT_INST in conf: for attr in [B.ATTR_INST_CNT, B.ATTR_INST_SGL]: if attr in conf[B.SUBJECT_INST]: out[attr] = conf[B.SUBJECT_INST][attr] return out def getComponents(job, mainfct): #job = basic.program.Job.getInstance() verify = -2 + job.getDebugLevel("job_tool") job.debug(verify, "getComponents " + mainfct) out = [] for c in comps: job.debug(verify, "getComponents " + c + ": " + str(comps[c].conf)) print("getComponents " + c + ": " + str(comps[c].conf)) if mainfct in comps[c].conf["function"]: out.append(c) return out class ComponentManager: __instance = None __instances = {} """ initializes the Manager with all necessary components """ def __init__(self, job, option=""): #job = basic.program.Job.getInstance() job.m.logDebug("applicationscomponente -- " + str(type(job.par))) self.components = {} self.comps = {} self.job = job ComponentManager.__instances[job.jobid] = self ComponentManager.__instance = self print ("init ComponentHandling "+str(self)) def initComponents(self): # sets components the first time # afterwards set components from parameter-file job = self.job # basic.program.Job.getInstance() anw = job.par.application job.m.logDebug("applicationscomponente -- " + str(type(job.par))) if not job.conf.confs[B.SUBJECT_APPS].get(anw): job.m.setFatal("application " + job.par.application + " is not configured") return for k in job.conf.confs[B.SUBJECT_APPS].get(anw): if k == B.ATTR_APPS_PROJECT: continue job.m.logDebug("applicationscomponente -- " + k + ":") print("applicationscomponente -- " + k + ":") self.createComponent(k, 0, "") def getComponent(self, compobjname): job = self.job #basic.program.Job.getInstance() verify = -2 + job.getDebugLevel("job_tool") job.debug(verify, "getComponents " + compobjname) if compobjname in self.comps: return self.comps[compobjname] return None def getComponents(self, mainfct): job = self.job #basic.program.Job.getInstance() verify = -2 + job.getDebugLevel("job_tool") job.debug(verify, "getComponents " + mainfct) out = [] for c in self.comps: job.debug(verify, "getComponents " + c + ": " + str(self.comps[c].conf)) print("getComponents " + c + ": " + str(self.comps[c].conf)) if mainfct in self.comps[c].conf["function"]: out.append(c) return out @staticmethod def getInstance(job, init="N"): if (job.jobid in ComponentManager.__instances): return ComponentManager.__instances[job.jobid] else: return ComponentManager(job) def createComponent(self, componentName, nr, suffix): """ in order to create a component it must be loaded * knogwedge of the application - which components should be created * technical-knowledge of the instanciated component, especially the connection, user, password * business-knowledge of the component, especially of their interfaces resp. artifacts :param componentName: Name of the component :param nr: for numbered instance if component is multiple :param suffix: suffix for specific context of the component :return: """ job = self.job #basic.program.Job.getInstance() verify = job.getDebugLevel("job_tool") componentName = componentName.lower() job.debug(verify, "createComponent " + componentName) confs = utils.config_tool.getConfig(job, "comp", componentName) conns = utils.conn_tool.getConnections(job, componentName) instAttr = getInstanceAttributes(confs) job.debug(verify, "createComponent -91- " + componentName + " : " + str(confs)) if nr > 0 and int(instAttr[B.ATTR_INST_CNT]) > 1: job.m.setError("for multiple callers are multiple calls not implemented ") if nr > 0 and len(conns) == 0: job.m.setError("for multiple calls has only one call configured") print(confs) parContent = job.loadParameter() if len(conns) == 1: c = self.createInstance(componentName, parContent, confs, conns, 0) print("createComponent 3 a " + componentName) self.createSubComponents(c, nr, suffix) else: i = 1 print("createComponent 3 b " + componentName) for cn in conns: c = self.createInstance(componentName, parContent, confs, conns, i) self.createSubComponents(c, i, suffix) i = i + 1 print("createComponent 9 " + componentName) print(self.comps) def createInstance(self, compName, parContent, confs, conns, nr): """ instance a component :param compName: name without suffix or number :param parContent: content of the parameter-file which is dumped from a pre-step :param confs: configuration of the component :param conns: connection-attributes for the specific environment :param nr: number if component is multiple :return: instance of the component with all necessary attributes """ job = self.job #basic.program.Job.getInstance() cmodul = importlib.import_module(getComponentPath(compName)) class_ = getattr(cmodul, getComponentClass(compName)) c = class_() if nr > 0: name = compName + "_0" + str(nr) i = nr - 1 else: name = compName i = 0 c.name = name c.classname = compName c.m = basic.message.Message(job, basic.message.LIMIT_DEBUG, "logTime", name) c.conf = utils.config_tool.mergeConn(c.m, confs["conf"], conns[i]) c.conf[B.SUBJECT_CONN] = conns[i] c.init(job) if parContent is not None: print("createComponent 5 a " + compName + " : " + str(parContent)) if B.SUBJECT_COMPS in parContent and compName in parContent[B.SUBJECT_COMPS]: for k in parContent[B.SUBJECT_COMPS][compName].keys(): c.conf[k] = parContent[B.SUBJECT_COMPS][compName][k] if B.SUBJECT_ARTS in c.conf and B.TOPIC_NODE_DB in c.conf[B.SUBJECT_ARTS]: if not B.DATA_NODE_DDL in c.conf: c.conf[B.DATA_NODE_DDL] = {} for table in c.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB]: if table in B.LIST_DB_ATTR: continue conf = utils.config_tool.getConfig(job, D.DDL_FILENAME, compName, table) if B.DATA_NODE_TABLES in conf and table in conf[B.DATA_NODE_TABLES]: c.conf[B.DATA_NODE_DDL][table] = conf[B.DATA_NODE_TABLES][table] elif table in conf: c.conf[B.DATA_NODE_DDL][table] = conf[table] else: c.conf[B.DATA_NODE_DDL][table] = conf comps[name] = c self.comps[name] = c return c def createSubComponents(self, comp, nr, suffix): job = self.job #basic.program.Job.getInstance() verify = -2 + job.getDebugLevel("job_tool") job.debug(verify, "getComponents " + str(comp.conf[B.ATTR_INST_SUBCOMP])) for c in comp.conf[B.ATTR_INST_SUBCOMP].keys(): if c == "none": continue self.createComponent(c, nr, suffix) def getComponentDict(self): job = self.job #basic.program.Job.getInstance() verify = -2 + job.getDebugLevel("job_tool") job.debug(verify, "getComponents ") out = {} for c in self.comps: out[self.comps[c].name] = {} for k in self.comps[c].conf.keys(): if isParameterSubnode(k): # B.SUBJECT_ARTS in k or "components" in k or "instance" in k: out[self.comps[c].name][k] = copy.deepcopy(self.comps[c].conf[k]) return out def getComponentFolder(comp): return comp.lower() def getComponentModul(comp): return comp[0:1].upper() + comp[1:].lower() def getComponentClass(comp): return comp[0:1].upper() + comp[1:].lower() def getComponentPath(comp): return "components." + getComponentFolder(comp) + "." + getComponentModul(comp) def getComponentDict(job = None): #job = basic.program.Job.getInstance() #verify = -2 + job.getDebugLevel("job_tool") #job.debug(verify, "getComponents ") out = {} for c in comps: out[comps[c].name] = {} for k in comps[c].conf.keys(): if isParameterSubnode(k): # B.SUBJECT_ARTS in k or "components" in k or "instance" in k: out[comps[c].name][k] = copy.deepcopy(comps[c].conf[k]) return out def isParameterSubnode(key): for k in PARAM_NOSUBNODE: if key in k: return False return True def getPlainCompname(name): if "_0" in name: return name[0:-3] return name