#OrchestratorDraftCommit (BigRefactoring, ProcessingConsolidation)

Signed-off-by: Ivan Maslov <Ivan.Maslov@UnicodeLabs.ru>
dev-linux
Ivan Maslov 5 years ago
parent 22d089213f
commit d145cec21d

@ -48,6 +48,7 @@ def RenderRobotR01(inGlobalConfiguration):
#Process not running #Process not running
lResultDict["FooterText"]=f'Дата изменения: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}' lResultDict["FooterText"]=f'Дата изменения: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}'
return lResultDict return lResultDict
def CheckIfProcessRunning(processName): def CheckIfProcessRunning(processName):
''' '''
Check if there is any running process that contains the given name processName. Check if there is any running process that contains the given name processName.
@ -76,78 +77,45 @@ mDict = {
] ]
}, },
"Scheduler":{ "Scheduler":{
"ActivityTimeCheckLoopSeconds_":"Количество секунд, между циклами проверки действий", "ActivityTimeCheckLoopSeconds":5, #Количество секунд, между циклами проверки действий
"ActivityTimeCheckLoopSeconds":5,
"ActivityTimeList":[ "ActivityTimeList":[
{ {
"description":"Запуск Python консоли", "TimeHH:MM":"19:25", #Time [HH:MM] to trigger activity
"__processCode":"Код процесса в openRPA daemon. Данные код может использоваться в дальнейшем для того, чтобы завершить именно тот процесс, который пораждался этой программой", "WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"processCode":"PythonDebug", "Activity":{
"__activityType":"processStart/processStop", "Type":"ProcessStart", #Activity type
"activityType":"processStart", "Path":"Notepad", #Executable file path
"__time":"__Время запуска активности", "ArgList": [] #List of the arguments
"time":"22:57", }
"__timeZone":"Часовой пояс, в рамках которого указано время. По-умолчанию часовой пояс МСК (GMT+4). Формат UTC offset in the form ±HHMM[SS[.ffffff]] ",
"timeZone":"+0400",
"__processPath":"Полный путь/наименование процесса. Запуск производится через subprocess. Идентификатор процесса в дальнейшем сохраняется и его можно будет закрыть с помощью параметра processCode",
"____processPath":"C:\\Abs\\Archive\\scopeSrcUL\\OpenRPA\\OpenRPA_32.cmd",
"processPath":"C:\\Abs\\Archive\\scopeSrcUL\\OpenRPA\\Orchestrator\\RobotDaemon\\runProcessOpenRPARobotDaemon_x32.cmd",
"__processArgs":"Аргументы, передаваемые при запуске процесса",
"processArgs":"",
"__weekdayNumList":"Список номеров дней недели, по которым выполнять инициализаци активности. Отсчет ведется от 0 до 6",
"weekdayNumList":[1,2,3]
},
{
"description":"Запуск Python консоли",
"__activityType":"processStart/processStop",
"activityType":"processStart",
"__time":"__Время запуска активности",
"time":"23:24",
"__timeZone":"Часовой пояс, в рамках которого указано время. По-умолчанию часовой пояс МСК (GMT+4). Формат UTC offset in the form ±HHMM[SS[.ffffff]] ",
"timeZone":"+0400",
"__processPath":"Полный путь/наименование процесса. Запуск производится через subprocess. Идентификатор процесса в дальнейшем сохраняется и его можно будет закрыть с помощью параметра processCode",
"processPath":"notepad",
"processArgs":""
}, },
{ {
"description":"Остановка Python консоли", "TimeHH:MM":"19:20", #Time [HH:MM] to trigger activity
"activityType":"processStop", "WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"time":"19:20", "Activity":{
"timeZone":"4", "Type":"ProcessStop", #Activity type
"processName":"OpenRPARobotDaemon.exe", "Name":"OpenRPARobotDaemon.exe", #Process name
"_flagCloseForce":"Признак, что процесс нужно принудительно закрыть (если флага нет, то на процесс просто посылается команда terminate)", "FlagForce":True, #Force process close
"flagCloseForce":True, "User": "%username%" #Empty, user or %username%
"_flagCloseOnlyCurrentUser":"Признак, что процесс нужно закрыть только у текущего пользователя", }
"flagCloseOnlyCurrentUser":True
}, },
{ {
"activityType":"loopActivity", "TimeHH:MMStart":"19:20", #Time [HH:MM] to trigger activity
"loopSeconds":6, "TimeHH:MMStop":"19:20",
"loopTimeStart":"21:45", "ActivityIntervalSeconds":5,
"loopTimeEnd":"21:46", "WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"pythonPackageName":"CheckActivity", "Activity":{
"pythonFunctionName":"test_activity", "Type": "PythonStart", #Activity type
"pythonFunctionArgList":["TestArg1","TestArg2"], "ModuleName": "CheckActivity", #Python function module name
"processPath":"notepad", "FunctionName": "test_activity", #Python function name
"processArgs":"" "ArgList": ["TestArg1","TestArg2"] #Input python function args
}
} }
],
] "LogList":[]
}, },
"Processor":{ "Processor":{
"LogList_":"Fill list when orchestrator is running", "LogType_CMDStart":True, #LogType_<Type>: <bool> if Trace for command is selected for False, the tracing will be off for such activity type. Default True
"TransactionList_":"List of processor activity, whick was executed", "LogList":[] #List of processor activity, which was executed. Fill list when orchestrator is running
"TransactionList__":[
{
"DateTimeStart":"2009-09-01T00:00:00.000Z",
"DateTimeEnd":"2009-09-01T00:00:00.000Z",
"ActivityList":[]
}
],
"TransactionList":[],
"TransactionTrace_<ActivityTypeName>":"<bool> if Trace for command is selected for False, the tracing will be off for such activity type",
"TransactionTrace_ActivityCMDRun":True,
}, },
"ControlPanelDict":{ "ControlPanelDict":{
"RefreshSeconds": 5, "RefreshSeconds": 5,

@ -72,11 +72,15 @@
////////////////////////// //////////////////////////
mGlobal.Controller={}; mGlobal.Controller={};
mGlobal.Controller.CMDRunText=function(inCMDText) { mGlobal.Controller.CMDRunText=function(inCMDText) {
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": inCMDText}
]
///Обнулить таблицу ///Обнулить таблицу
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+inCMDText+'"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3){}, function(lData,l2,l3){},
dataType: "text" dataType: "text"
@ -85,10 +89,14 @@
mGlobal.Controller.CMDRun=function() { mGlobal.Controller.CMDRun=function() {
///Обнулить таблицу ///Обнулить таблицу
lCMDCode=$(".openrpa-controller-cmd-run-input")[0].value lCMDCode=$(".openrpa-controller-cmd-run-input")[0].value
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": lCMDCode }
]
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+lCMDCode+'"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
@ -102,19 +110,23 @@
mGlobal.Controller.CMDRunGUILogout=function() { mGlobal.Controller.CMDRunGUILogout=function() {
///Обнулить таблицу ///Обнулить таблицу
lCMDCode="for /f \"skip=1 tokens=2\" %s in ('query user %USERNAME%') do (tscon \\dest:console)" lCMDCode="for /f \"skip=1 tokens=2\" %s in ('query user %USERNAME%') do (tscon \\dest:console)"
lCMDCode = lCMDCode.replace(/\\n/g, "\\n") //lCMDCode = lCMDCode.replace(/\\n/g, "\\n")
.replace(/\\'/g, "\\'") // .replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"') // .replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&") // .replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r") // .replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t") // .replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b") // .replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f") // .replace(/\\f/g, "\\f")
.replace('"', "\\\""); // .replace('"', "\\\"");
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": lCMDCode }
]
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+lCMDCode+'"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
@ -129,10 +141,14 @@
///Перезагрузить Orchestrator ///Перезагрузить Orchestrator
mGlobal.Controller.OrchestratorRestart=function() { mGlobal.Controller.OrchestratorRestart=function() {
///Подготовить конфигурацию
lData = [
{"Type":"OrchestratorRestart"}
]
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"ActivityRestartOrchestrator"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
@ -233,11 +249,21 @@
mGlobal.Test=function() { mGlobal.Test=function() {
///Обнулить таблицу ///Обнулить таблицу
lData = [
{
"Type":"GlobalDictKeyListValueSet",
"key_list":["Storage","Robot_R01"],
"value":{
"RunDateTimeString":"Test1",
"StepCurrentName":"Test2",
"StepCurrentDuration":"Test3"
}
}
]
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"AdministrationGlobalDictSetKeyListValue","key_list":["Storage","Robot_R01"],"value":{"RunDateTimeString":"Test1","StepCurrentName":"Test2","StepCurrentDuration":"Test3"}}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
@ -253,10 +279,16 @@
mGlobal.Scheduler = {} mGlobal.Scheduler = {}
mGlobal.Scheduler.ActivityTimeListShow = function() { mGlobal.Scheduler.ActivityTimeListShow = function() {
lData = [
{
"Type":"GlobalDictKeyListValueGet",
"KeyList":["Scheduler","ActivityTimeList"]
}
]
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"PlanLogListGet"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
@ -278,12 +310,18 @@
mGlobal.Processor = {} mGlobal.Processor = {}
mGlobal.Processor.LogListShow = function() { mGlobal.Processor.LogListShow = function() {
lData = [
{
"Type":"GlobalDictKeyListValueGet",
"KeyList":["Processor","LogList"]
}
]
///Обнулить таблицу ///Обнулить таблицу
$('.ui.modal.basic .content').html(""); $('.ui.modal.basic .content').html("");
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'ProcessingRun', url: 'Utils/Processor',
data: '{"actionList":[{"type":"ActivityLogScheduleListGet"}]}', data: JSON.stringify(lData),
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {

@ -8,6 +8,7 @@ import signal
import pdb import pdb
import orchestratorServer import orchestratorServer
import orchestratorTimer import orchestratorTimer
import orchestratorProcessor
import logging import logging
from Settings import Settings from Settings import Settings
@ -24,6 +25,10 @@ lGlobalDict={}
lDaemonConfigurationObject=Settings.mDict lDaemonConfigurationObject=Settings.mDict
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
mGlobalDict = Settings.Dict
#Инициализация настроечных параметров #Инициализация настроечных параметров
lDaemonLoopSeconds=lDaemonConfigurationObject["Scheduler"]["ActivityTimeCheckLoopSeconds"] lDaemonLoopSeconds=lDaemonConfigurationObject["Scheduler"]["ActivityTimeCheckLoopSeconds"]
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>) lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
@ -44,82 +49,53 @@ while True:
lCurrentDateTime=datetime.datetime.now() lCurrentDateTime=datetime.datetime.now()
#Циклический обход правил #Циклический обход правил
lFlagSearchActivityType=True lFlagSearchActivityType=True
for lItem in lDaemonConfigurationObject["Scheduler"]["ActivityTimeList"]: for lIndex, lItem in enumerate(lDaemonConfigurationObject["Scheduler"]["ActivityTimeList"]):
#Проверка дней недели, в рамках которых можно запускать активность #Проверка дней недели, в рамках которых можно запускать активность
lItemWeekdayList=lItem.get("weekdayNumList",[0,1,2,3,4,5,6]) lItemWeekdayList=lItem.get("WeekdayList",[0,1,2,3,4,5,6])
if lCurrentDateTime.weekday() in lItemWeekdayList: if lCurrentDateTime.weekday() in lItemWeekdayList:
if lFlagSearchActivityType: if lFlagSearchActivityType:
#Определить вид активности #Лог
if lItem["activityType"]=="processStart": lItemCopy = copy.deepcopy(lItem)
lItemCopy["DateTimeUTCStringStart"]=datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
mGlobalDict["Scheduler"]["LogList"].append(lItemCopy)
#######################################################################
#Branch 1 - if has TimeHH:MM
#######################################################################
if "TimeHH:MM" in lItem:
#Вид активности - запуск процесса #Вид активности - запуск процесса
#Сформировать временной штамп, относительно которого надо будет проверять время #Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем #часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["time"],"%H:%M") lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MM"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило #Убедиться в том, что время наступило
if ( if (
lActivityDateTime>=lDaemonStartDateTime and lActivityDateTime>=lDaemonStartDateTime and
lCurrentDateTime>=lActivityDateTime and lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict): (lIndex,lActivityDateTime) not in lDaemonActivityLogDict):
#Выполнить операцию #Выполнить операцию
print(datetime.datetime.now().isoformat()+":: ProcessStart:"+lItem["processPath"])
logging.info("ProcessStart:"+lItem["processPath"])
#Запись в массив отработанных активностей #Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime} lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс #Запустить процесс
lItemArgs=[lItem["processPath"]] orchestratorProcessor.ActivityListOrDict(lItem["Activity"])
lItemArgs.extend(lItem["processArgs"]) #######################################################################
subprocess.Popen(lItemArgs,shell=True) #Banch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds
#Определить вид активности #######################################################################
if lItem["activityType"]=="processStop": if "TimeHH:MMStart" in lItem and "TimeHH:MMStop" in lItem and "ActivityIntervalSeconds" in lItem:
#Вид активности - остановка процесса
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["time"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило
if (
lActivityDateTime>=lDaemonStartDateTime and
lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processName"]) not in lDaemonActivityLogDict):
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processName"])]={"ActivityStartDateTime":lCurrentDateTime}
#Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem.get('flagCloseForce',False):
lActivityCloseCommand+=" /F"
#Завершить процессы только текущего пользоваиеля
if lItem.get('flagCloseOnlyCurrentUser',False):
lActivityCloseCommand+=' /fi "username eq %username%"'
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)})
#Завершить процесс
os.system(lActivityCloseCommand)
print(datetime.datetime.now().isoformat()+":: ProcessStop "+lItem["processName"])
logging.info("ProcessStop "+lItem["processName"])
#Вид активности - запуск отдельного потока с циклическим вызовом
if lItem["activityType"]=="loopActivity":
#Сформировать временной штамп, относительно которого надо будет проверять время #Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем #часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["loopTimeStart"],"%H:%M") lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStart"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["loopTimeEnd"],"%H:%M") lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStop"],"%H:%M")
lActivityTimeEndDateTime=lActivityTimeEndDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) lActivityTimeEndDateTime=lActivityTimeEndDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило #Убедиться в том, что время наступило
if ( if (
lCurrentDateTime<lActivityTimeEndDateTime and lCurrentDateTime<lActivityTimeEndDateTime and
lCurrentDateTime>=lActivityDateTime and lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict): (lIndex,lActivityDateTime) not in lDaemonActivityLogDict):
logging.info("ActivityLoop Start ")
#Запись в массив отработанных активностей #Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime} lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
#Запуск циклической процедуры #Запуск циклической процедуры
orchestratorTimer.activityLoopStart(lItem["loopSeconds"],lItem["processPath"],lItem["processArgs"],lActivityTimeEndDateTime,lItem["pythonPackageName"],lItem["pythonFunctionName"],lItem["pythonFunctionArgList"]) orchestratorTimer.activityLoopStart(lItem["ActivityIntervalSeconds"],lActivityTimeEndDateTime, lItem["Activity"])
#Уснуть до следующего прогона #Уснуть до следующего прогона
time.sleep(lDaemonLoopSeconds) time.sleep(lDaemonLoopSeconds)

@ -6,143 +6,184 @@ import os
import sys import sys
import subprocess import subprocess
import copy import copy
import win32ts import importlib
#Глобальная переменная - все глобальные значения программы #Input arg
global mGlobalDict
#Включить WTS (WIN32TS)
mWTSServer = lWTSServer = win32ts.WTSOpenServer("localhost")
#{
# actionList:
# [ # [
# { # {
# type: <RemoteMachineProcessingRun>, # "Type": <RemoteMachineProcessingRun>,
# host: <localhost>, # host: <localhost>,
# port: <port>, # port: <port>,
# bodyObject: <object dict, int, str, list> # bodyObject: <object dict, int, str, list>
# }, # },
# { # {
# type: <ActivityLogScheduleListGet> # "Type": "CMDStart",
# "Command": ""
# }, # },
# { # {
# type: <ActivityCMDRun>, # "Type": "OrchestratorRestart"
# code: <str>
# }, # },
# { # {
# type: <ActivityRestartOrchestrator> # "Type": "GlobalDictKeyListValueSet",
# "KeyList": ["key1","key2",...],
# "Value": <List, Dict, String, int>
# }, # },
# { # {
# type: <ActivitySessionCheckSetActive> # "Type": "GlobalDictKeyListValueGet",
# "KeyList": ["key1","key2",...]
# }, # },
# { # {
# type: <AdministrationGlobalDictSetKeyListValue> # "Type":"ProcessStart",
# key_list: ["key1","key2",...] # "Path":"",
# value: <List, Dict, String, int> # "ArgList":[]
#
# }, # },
# { # {
# type: <AdministrationGlobalDictGetKeyListValue> # "Type":"ProcessStop",
# key_list: ["key1","key2",...] # "Name":"",
# "FlagForce":True,
# "User":"" #Empty, user or %username%
# }, # },
# {
# "Type":"PythonStart",
# "ModuleName":"",
# "FunctionName":"",
# "ArgList":[],
# "ArgDict":{}
# }
# ] # ]
# ##################################
#} #Output result
# <input arg> with attributes:
def ProcessingRun(inConfigurationDict): # "DateTimeUTCStringStart"
#print(mGlobalDict) # "DateTimeUTCStringStop"
lDateTimeString=datetime.datetime.strftime(datetime.datetime.now(),"%Y.%m.%d %H:%M:%S::%f") # "Result"
lResult={"dateTime":lDateTimeString, "state":"connected", "actionListResult":[]} def Activity(inActivity):
lTransactionItem={} #Глобальная переменная - глобальный словарь унаследованный от Settings.py
#Transaction start global mGlobalDict
lTransactionItem["DateTimeStart"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f") #Fill DateTimeUTCStringStart
lTransactionItem["ActivityList"]=[] inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
for lItem in inConfigurationDict["actionList"]: #Alias (compatibility)
#Добавить входные значения lItem = inActivity
lResult["actionListResult"].append({"inArgs":lItem}) ###########################################################
#Обработка запроса на отправку команды на удаленную машину #Обработка запроса на отправку команды на удаленную машину
if lItem["type"]=="RemoteMachineProcessingRun": ###########################################################
lHTTPConnection = http.client.HTTPConnection(lItem["host"], lItem["port"], timeout=5) if lItem["Type"]=="RemoteMachineProcessingRun":
try: lHTTPConnection = http.client.HTTPConnection(lItem["host"], lItem["port"], timeout=5)
lHTTPConnection.request("POST","/ProcessingRun",json.dumps(lItem["bodyObject"])) try:
except Exception as e: lHTTPConnection.request("POST","/ProcessingRun",json.dumps(lItem["bodyObject"]))
#Объединение словарей except Exception as e:
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"state":"disconnected","errorMessage":str(e)}} #Объединение словарей
#lResult["actionListResult"][-1].join({"state":"disconnected","errorMessage":str(e)}) lItem["Result"] = {"State":"disconnected","ExceptionString":str(e)}
else:
lHTTPResponse=lHTTPConnection.getresponse()
lHTTPResponseByteArray=lHTTPResponse.read()
lItem["Result"] = json.loads(lHTTPResponseByteArray.decode('utf8'))
###########################################################
#Обработка команды CMDStart
###########################################################
if lItem["Type"]=="CMDStart":
lCMDCode="cmd /c "+lItem["code"]
subprocess.Popen(lCMDCode)
lResultCMDRun=1#os.system(lCMDCode)
lItem["Result"] = str(lResultCMDRun)
###########################################################
#Обработка команды OrchestratorRestart
###########################################################
if lItem["Type"]=="OrchestratorRestart":
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv)
lItem["Result"] = True
sys.exit(0)
###########################################################
#Обработка команды GlobalDictKeyListValueSet
###########################################################
if lItem["Type"]=="GlobalDictKeyListValueSet":
for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists
if lItem2 in mGlobalDict:
pass
else: else:
lHTTPResponse=lHTTPConnection.getresponse() mGlobalDict[lItem2]={}
lHTTPResponseByteArray=lHTTPResponse.read() mGlobalDict=mGlobalDict[lItem2]
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **json.loads(lHTTPResponseByteArray.decode('utf8'))} #Set value
#Обработка команды ActivityLogScheduleListGet mGlobalDict[lItem["KeyList"][-1]]=lItem["value"]
if lItem["type"]=="ActivityLogScheduleListGet": ###########################################################
#pdb.set_trace() #Обработка команды GlobalDictKeyListValueGet
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":mGlobalDict["ActivityLogScheduleList"]}} ###########################################################
#Обработка команды PlanLogListGet if lItem["type"]=="GlobalDictKeyListValueGet":
if lItem["type"]=="PlanLogListGet": for lItem2 in lItem["KeyList"][:-1]:
#pdb.set_trace() #Check if key - value exists
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":mGlobalDict["JSONConfigurationDict"]["Scheduler"]["ActivityTimeList"]}} if lItem2 in mGlobalDict:
#Обработка команды ActivityCMDRun pass
if lItem["type"]=="ActivityCMDRun": else:
lCMDCode="cmd /c "+lItem["code"] mGlobalDict[lItem2]={}
subprocess.Popen(lCMDCode) mGlobalDict=mGlobalDict[lItem2]
lResultCMDRun=1#os.system(lCMDCode) #Return value
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":str(lResultCMDRun)}} lItem["Result"]==mGlobalDict.get(lItem["KeyList"][-1],None)
#Обработка команды ActivityRestartOrchestrator #Определить вид активности
if lItem["type"]=="ActivityRestartOrchestrator": lActivityDateTime=inActivity["DateTimeUTCStringStart"]
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv) #####################################
sys.exit(0) #ProcessStart
#Обработка команды ActivitySessionCheckSetActive #####################################
if lItem["type"]=="ActivitySessionCheckSetActive": if lItem["Type"]=="ProcessStart":
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":{"IsActivated":False}}} #Вид активности - запуск процесса
lPID = os.getpid() #Запись в массив отработанных активностей
#pdb.set_trace() lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime}
lSessionId = win32ts.ProcessIdToSessionId(lPID) #Лог
lSessionList = win32ts.WTSEnumerateSessions(lWTSServer) mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
#При попытке закрыть сервер возникает ошибка #Запустить процесс
#win32ts.WTSCloseServer(lWTSServer) lItemArgs=[lItem["processPath"]]
#Наложить фильтр lItemArgs.extend(lItem["processArgs"])
lSessionFiltered = [d for d in lSessionList if d["SessionId"]==lSessionId] subprocess.Popen(lItemArgs,shell=True)
#Выполнить переход в активное состояние , если State != 0 #################################
if lSessionFiltered[0]["State"] != 0: #ProcessStop
lCMDCodeTSCON = "tscon " + str(lSeessionId) + " /dest:console" #################################
lCMDCode="cmd /c "+lCMDCodeTSCON if lItem["Type"]=="ProcessStop":
subprocess.Popen(lCMDCode) #Вид активности - остановка процесса
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":{"IsActivated":True}}} #часовой пояс пока не учитываем
#Выключить соединение #Запись в массив отработанных активностей
#Обработка команды AdministrationGlobalDictSetKeyListValue lDaemonActivityLogDict[(lItem["Type"],lActivityDateTime,lItem["Name"])]={"ActivityStartDateTime":lCurrentDateTime}
if lItem["type"]=="AdministrationGlobalDictSetKeyListValue": #Сформировать команду на завершение
lGlobalDict=mGlobalDict["JSONConfigurationDict"] lActivityCloseCommand='taskkill /im '+lItem["processName"]
for lItem2 in lItem["key_list"][:-1]: #TODO Сделать безопасную обработку,если параметра нет в конфигурации
#Check if key - value exists if lItem.get('FlagForce',False):
if lItem2 in lGlobalDict: lActivityCloseCommand+=" /F"
pass #Завершить процессы только текущего пользоваиеля
else: if lItem.get('User',"")!="":
lGlobalDict[lItem2]={} lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"'
lGlobalDict=lGlobalDict[lItem2] #Лог
#Set value mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)})
#pdb.set_trace() #Завершить процесс
lGlobalDict[lItem["key_list"][-1]]=lItem["value"] os.system(lActivityCloseCommand)
#Обработка команды AdministrationGlobalDictGetKeyListValue #################################
if lItem["type"]=="AdministrationGlobalDictGetKeyListValue": #PythonStart
lGlobalDict=mGlobalDict["JSONConfigurationDict"] #################################
for lItem2 in lItem["key_list"][:-1]: if lItem["Type"]=="PythonStart":
#Check if key - value exists try:
if lItem2 in lGlobalDict: #Подключить модуль для вызова
pass lModule=importlib.import_module(lItem["ModuleName"])
else: #Найти функцию
lGlobalDict[lItem2]={} lFunction=getattr(lModule,lItem["FunctionName"])
lGlobalDict=lGlobalDict[lItem2] lItem["Result"]=lFunction(*lItem.get("ArgList",[]),**lItem.get("ArgDict",{}))
#Set value except Exception as e:
#pdb.set_trace() logging.exception("Loop activity error: module/function not founded")
lResult["actionListResult"][-1]["key_list"]=lItem["key_list"] #Set datetime stop
lResult["actionListResult"][-1]["value"]=lGlobalDict.get(lItem["key_list"][-1],None) lItem["DateTimeUTCStringStop"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
################## ##################
#Trace activity #Trace activity
################## ##################
if mGlobalDict["Processor"].get(f"TransactionTrace_{lItem['type']}",True): if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True):
#Add activity in TransactionList if it is applicable #Add activity in TransactionList if it is applicable
lTransactionItem["ActivityList"].append(copy.deepcopy(lItem)) mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem))
#Transaction end
lTransactionItem["DateTimeEnd"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
#Перенос результатов в TransactionList
mGlobalDict["Processor"]["TransactionList"].append(lTransactionItem)
#Вернуть результат #Вернуть результат
return lResult return lItem
def ActivityListOrDict(inActivityListOrDict):
#Check arg type (list or dict)
if type(inActivityListOrDict)==list:
#List activity
for lItem in inActivityListOrDict:
lResult.append(Activity(lItem))
return lResult
if type(inActivityListOrDict)==dict:
#Dict activity
return Activity(inActivityListOrDict)

@ -162,7 +162,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST # POST
def do_POST(self): def do_POST(self):
#Централизованная функция получения запросов/отправки #Централизованная функция получения запросов/отправки
if self.path == '/ProcessingRun': if self.path == '/Utils/Processor':
#ReadRequest #ReadRequest
lInputObject={} lInputObject={}
if self.headers.get('Content-Length') is not None: if self.headers.get('Content-Length') is not None:
@ -176,7 +176,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.send_header('Content-type','application/json') self.send_header('Content-type','application/json')
self.end_headers() self.end_headers()
# Send message back to client # Send message back to client
message = json.dumps(orchestratorProcessor.ProcessingRun(lInputObject)) message = json.dumps(orchestratorProcessor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data # Write content as utf-8 data
self.wfile.write(bytes(message, "utf8")) self.wfile.write(bytes(message, "utf8"))
return return

@ -3,6 +3,7 @@ import datetime
import subprocess import subprocess
import importlib import importlib
import logging import logging
import orchestratorProcessor
class RepeatedTimer(object): class RepeatedTimer(object):
def __init__(self, interval, function, *args, **kwargs): def __init__(self, interval, function, *args, **kwargs):
self._timer = None self._timer = None
@ -31,31 +32,11 @@ class RepeatedTimer(object):
############################################################ ############################################################
####Техническая функция обработки таймера - потока ####Техническая функция обработки таймера - потока
############################################################ ############################################################
def activityLoopExecution(inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList=[]): def activityLoopExecution(inLoopTimeEndDateTime, inActivity):
lResultGoLoop=True lResultGoLoop=True
lCurrentDateTime=datetime.datetime.now() lCurrentDateTime=datetime.datetime.now()
print (datetime.datetime.now().isoformat()+":: Loop activity check") #Запустить актитвость через процессор (orchestratorProcessor)
logging.info("Loop activity check") orchestratorProcessor.ActivityListOrDict(inActivity)
#Запустить процесс, если установлен inProcessPath
if inProcessPath is not None:
if inProcessPath != "":
lItemArgs=[inProcessPath]
lItemArgs.extend(inProcessArgList)
subprocess.Popen(lItemArgs,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Импорт Python пакета и запуск функции из него
if inPythonPackageName is not None:
if inPythonPackageName != "":
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inPythonPackageName)
#Найти функцию
lFunction=getattr(lModule,inPythonFunctionName)
lFunction(*inPythonFunctionArgList)
except Exception as e:
print (datetime.datetime.now().isoformat()+":: Loop activity error: module/function not founded")
logging.info("Loop activity error: module/function not founded")
#Выключить таймер, если время наступило #Выключить таймер, если время наступило
if lCurrentDateTime>=inLoopTimeEndDateTime: if lCurrentDateTime>=inLoopTimeEndDateTime:
lResultGoLoop=False lResultGoLoop=False
@ -64,6 +45,6 @@ def activityLoopExecution(inProcessPath,inProcessArgList,inLoopTimeEndDateTime,i
############################################################ ############################################################
####Функция запуска таймера - потока ####Функция запуска таймера - потока
############################################################ ############################################################
def activityLoopStart(inActivityLoopSeconds,inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList=[]): def activityLoopStart(inActivityLoopSeconds, inLoopTimeEndDateTime, inActivity):
lTimer = RepeatedTimer(inActivityLoopSeconds, activityLoopExecution, inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList) # it auto-starts, no need of rt.start() lTimer = RepeatedTimer(inActivityLoopSeconds, activityLoopExecution, inLoopTimeEndDateTime, inActivity) # it auto-starts, no need of rt.start()
lTimer.start() lTimer.start()

@ -0,0 +1,5 @@
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (
%windir%\System32\tscon.exe %%s /dest:console
)
timeout 10
QRes.exe /x 1680 /y 1050
Loading…
Cancel
Save