biz-a-cli 2.3.1 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/hub.js +44 -65
- package/bin/hubEvent.js +72 -0
- package/bin/index.js +67 -55
- package/bin/proxy.js +14 -11
- package/bin/watcher.js +49 -0
- package/callbackController.js +19 -0
- package/constanta.js +8 -0
- package/envs/env.dev.js +10 -0
- package/envs/env.js +10 -0
- package/mailController.js +26 -0
- package/package.json +31 -10
- package/proxyController.js +83 -0
- package/scheduler/configController.js +106 -0
- package/scheduler/converter.js +84 -0
- package/scheduler/datalib.js +200 -0
- package/scheduler/timer.js +83 -0
- package/scheduler/watcherController.js +105 -0
- package/scheduler/watcherlib.js +105 -0
- package/tests/converter.test.js +99 -0
- package/tests/data.test.js +80 -0
- package/tests/hub.test.js +87 -0
- package/tests/mailCtl.test.js +34 -0
- package/tests/timer.test.js +91 -0
- package/tests/watcher.test.js +350 -0
- package/tests/watcherCtl.test.js +128 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as https from 'https';
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
|
|
4
|
+
export function proxy(clientRequest, clientResponse) {
|
|
5
|
+
try {
|
|
6
|
+
const isHttps = url => url.startsWith('https://');
|
|
7
|
+
const hasPort = url => url.indexOf(':') > -1;
|
|
8
|
+
|
|
9
|
+
const targetUrl = clientRequest.query.target ?
|
|
10
|
+
clientRequest.query.target
|
|
11
|
+
: clientRequest.get('target');
|
|
12
|
+
const target = targetUrl.split('/')[2];
|
|
13
|
+
|
|
14
|
+
let parsedHost = targetUrl.split('/').splice(2).splice(0, 1).join('/');
|
|
15
|
+
if (hasPort(target)) parsedHost = parsedHost.split(':')[0];
|
|
16
|
+
let targetPort = hasPort(target) ? target.split(':')[1] : null;
|
|
17
|
+
|
|
18
|
+
const parsedSSL = isHttps(targetUrl) ? https : http;
|
|
19
|
+
|
|
20
|
+
// console.log(clientRequest.headers)
|
|
21
|
+
let svrReqHeader = {};
|
|
22
|
+
if (clientRequest.headers["content-type"]) {
|
|
23
|
+
svrReqHeader["content-type"] = clientRequest.headers["content-type"];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const options = {
|
|
27
|
+
hostname: parsedHost,
|
|
28
|
+
port: isHttps(targetUrl) ?
|
|
29
|
+
// (targetPort ? targetPort : 443) :
|
|
30
|
+
// (targetPort ? targetPort : 80),
|
|
31
|
+
(targetPort || 443) :
|
|
32
|
+
(targetPort || 80),
|
|
33
|
+
path: clientRequest.url,
|
|
34
|
+
method: clientRequest.method,
|
|
35
|
+
headers: svrReqHeader
|
|
36
|
+
};
|
|
37
|
+
if (clientRequest.headers['user-agent']) {
|
|
38
|
+
options['User-Agent'] = clientRequest.headers['user-agent'];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const serverRequest = parsedSSL.request(options, function (serverResponse) {
|
|
42
|
+
try {
|
|
43
|
+
let body = '';
|
|
44
|
+
if (serverResponse.headers['content-type'] && String(serverResponse.headers['content-type']).indexOf('text/html') !== -1) {
|
|
45
|
+
serverResponse.on('data', function (chunk) {
|
|
46
|
+
body += chunk;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
serverResponse.on('end', function () {
|
|
50
|
+
clientResponse.writeHead(serverResponse.statusCode, serverResponse.headers);
|
|
51
|
+
clientResponse.end(body);
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
serverResponse.pipe(clientResponse, {
|
|
55
|
+
end: true,
|
|
56
|
+
});
|
|
57
|
+
clientResponse.contentType(serverResponse.headers['content-type']);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.log('exception')
|
|
61
|
+
console.log(error);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
serverRequest.on('error', function (err) {
|
|
66
|
+
// clientResponse.writeHead(503, {Error: err.message});
|
|
67
|
+
console.log('On Error serverRequest Proxy: ', err);
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// console.log(clientRequest.body)
|
|
71
|
+
if (clientRequest.body) {
|
|
72
|
+
serverRequest.write(JSON.stringify(clientRequest.body));
|
|
73
|
+
}
|
|
74
|
+
serverRequest.end();
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.log(err);
|
|
77
|
+
|
|
78
|
+
// serverRequest.end();
|
|
79
|
+
// clientResponse.end();
|
|
80
|
+
serverRequest.destroy();
|
|
81
|
+
// clientResponse.destroy();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { MongoClient, ObjectId } from 'mongodb';
|
|
2
|
+
import { envDev } from '../envs/env.dev.js';
|
|
3
|
+
import { env } from '../envs/env.js';
|
|
4
|
+
|
|
5
|
+
let BIZA_MONGO_LINK;
|
|
6
|
+
let CDM_MONGO_LINK;
|
|
7
|
+
let COMPANY_REGISTER;
|
|
8
|
+
|
|
9
|
+
// if ((process.env.NODE_ENV == undefined) || (process.env.NODE_ENV == 'development')) {
|
|
10
|
+
// BIZA_MONGO_LINK = envDev.BIZA_MONGO_LINK;
|
|
11
|
+
// CDM_MONGO_LINK = envDev.CDM_MONGO_LINK;
|
|
12
|
+
// COMPANY_REGISTER = envDev.COMPANY_REGISTER;
|
|
13
|
+
|
|
14
|
+
// console.log('BIZA_MONGO_LINK =>', BIZA_MONGO_LINK);
|
|
15
|
+
// console.log('CDM_MONGO_LINK =>', CDM_MONGO_LINK);
|
|
16
|
+
// console.log('COMPANY_REGISTER =>', COMPANY_REGISTER);
|
|
17
|
+
// } else {
|
|
18
|
+
BIZA_MONGO_LINK = env.BIZA_MONGO_LINK;
|
|
19
|
+
CDM_MONGO_LINK = env.CDM_MONGO_LINK;
|
|
20
|
+
COMPANY_REGISTER = env.COMPANY_REGISTER;
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
async function fetchSelectedConfig(aggregateField) {
|
|
24
|
+
const client = new MongoClient(BIZA_MONGO_LINK);
|
|
25
|
+
try {
|
|
26
|
+
await client.connect();
|
|
27
|
+
const db = client.db('biz-a');
|
|
28
|
+
const config = db.collection('configuration');
|
|
29
|
+
|
|
30
|
+
return await config.aggregate(aggregateField).toArray();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error(error);
|
|
33
|
+
throw new Error(error);
|
|
34
|
+
} finally {
|
|
35
|
+
client.close()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getSelectedConfigAggregateField(companyObjectId) {
|
|
40
|
+
let configAggregate = [];
|
|
41
|
+
if (companyObjectId) {
|
|
42
|
+
configAggregate.push({ "$match": { companyObjectId: new ObjectId(companyObjectId) } });
|
|
43
|
+
};
|
|
44
|
+
configAggregate.push({
|
|
45
|
+
$lookup: {
|
|
46
|
+
from: 'smtp',
|
|
47
|
+
localField: '_id',
|
|
48
|
+
foreignField: 'configObjectId',
|
|
49
|
+
as: 'smtp'
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
configAggregate.push({ $unwind: { path: "$smtp" } });
|
|
53
|
+
|
|
54
|
+
return configAggregate;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function getSelectedConfig(companyObjectId) {
|
|
58
|
+
return await fetchSelectedConfig(getSelectedConfigAggregateField(companyObjectId));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getCompanyObjectIdFindOneField(companyName) {
|
|
62
|
+
return [
|
|
63
|
+
{ companyID: { $regex: new RegExp(`^${companyName}$`, 'i') } },
|
|
64
|
+
{
|
|
65
|
+
projection: {
|
|
66
|
+
_id: 1,
|
|
67
|
+
companyID: 1
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function fetchCompanyObjectId(findOneField) {
|
|
74
|
+
const client = new MongoClient(CDM_MONGO_LINK);
|
|
75
|
+
try {
|
|
76
|
+
await client.connect();
|
|
77
|
+
const db = client.db(COMPANY_REGISTER);
|
|
78
|
+
const company = db.collection('companies');
|
|
79
|
+
|
|
80
|
+
return await company.findOne(findOneField[0], findOneField[1]);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(error);
|
|
83
|
+
throw new Error(error);
|
|
84
|
+
} finally {
|
|
85
|
+
client.close()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function validateCompanyObjectId(companyObjectId) {
|
|
90
|
+
if (companyObjectId?._id) {
|
|
91
|
+
return companyObjectId;
|
|
92
|
+
} else {
|
|
93
|
+
throw { code: 'ENOENT' };
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
async function getCompanyObjectId(companyName) {
|
|
98
|
+
const companyObjectId = await fetchCompanyObjectId(getCompanyObjectIdFindOneField(companyName));
|
|
99
|
+
return validateCompanyObjectId(companyObjectId);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
BIZA_MONGO_LINK,
|
|
104
|
+
getSelectedConfig,
|
|
105
|
+
getCompanyObjectId
|
|
106
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export function historyRecordToJson(data) {
|
|
2
|
+
let dataJson = [];
|
|
3
|
+
data.map(history => {
|
|
4
|
+
dataJson.push({
|
|
5
|
+
_id: parseInt(history.history_id),
|
|
6
|
+
timerObjectId: parseInt(history.timer_id),
|
|
7
|
+
latestRun: new Date(history.latest_run)
|
|
8
|
+
})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
return dataJson;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function addTimer(timer, timerData) {
|
|
15
|
+
let timerIdx = (timerData) ? timerData.findIndex(value => value._id == timer.timer_id) : -1;
|
|
16
|
+
if (timerIdx > -1) {
|
|
17
|
+
if (timer.hourly_hours) {
|
|
18
|
+
timerData[timerIdx].hourly = timer.hourly_hours.split(',').map(String);
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
let timerObj = {
|
|
22
|
+
_id: parseInt(timer.timer_id),
|
|
23
|
+
watcherObjectId: parseInt(timer.timer_watcher_id),
|
|
24
|
+
name: timer.name,
|
|
25
|
+
active: (timer.active == 1),
|
|
26
|
+
timezone: timer.timezone,
|
|
27
|
+
templateName: timer.templateName,
|
|
28
|
+
seq: parseInt(timer.seq),
|
|
29
|
+
scriptId: parseInt(timer.scriptId),
|
|
30
|
+
script: (timer.cli_script) ? JSON.stringify(timer.cli_script) : ''
|
|
31
|
+
};
|
|
32
|
+
if ((timer.daily_days)) {
|
|
33
|
+
timerObj.daily = timer.daily_days.split(',').map(Number);
|
|
34
|
+
}
|
|
35
|
+
if (timer.weekly_ordinal && timer.weekly_days) {
|
|
36
|
+
timerObj.weekly = {
|
|
37
|
+
ordinal: timer.weekly_ordinal.split(',').map(Number),
|
|
38
|
+
days: timer.weekly_days.split(',').map(Number)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if ((timer.monthly_days)) {
|
|
42
|
+
timerObj.monthly = timer.monthly_days.split(',')
|
|
43
|
+
.map(value => (!isNaN(value)) ? Number(value) : value);
|
|
44
|
+
}
|
|
45
|
+
if (timer.minutely_everymin &&
|
|
46
|
+
timer.minutely_time_from && timer.minutely_time_to) {
|
|
47
|
+
timerObj.minutely = {
|
|
48
|
+
everyMin: parseInt(timer.minutely_everymin),
|
|
49
|
+
from: timer.minutely_time_from,
|
|
50
|
+
to: timer.minutely_time_to,
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
timerData.push(timerObj);
|
|
54
|
+
|
|
55
|
+
timerIdx = timerData.length - 1;
|
|
56
|
+
|
|
57
|
+
if (timer.hourly_hours) {
|
|
58
|
+
timerData[timerIdx].hourly = timer.hourly_hours.split(',').map(String);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return timerData;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function watcherRecordToJson(data) {
|
|
65
|
+
let dataJson = [];
|
|
66
|
+
data.map(timer => {
|
|
67
|
+
let watcherIdx = (dataJson) ? dataJson.findIndex(value => value._id == timer.watcher_id) : -1;
|
|
68
|
+
|
|
69
|
+
if (watcherIdx > -1) {
|
|
70
|
+
addTimer(timer, dataJson[watcherIdx].timer);
|
|
71
|
+
} else {
|
|
72
|
+
dataJson.push({
|
|
73
|
+
_id: parseInt(timer.watcher_id),
|
|
74
|
+
companyObjectId: timer.company_id,
|
|
75
|
+
timer: []
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
watcherIdx = dataJson.length - 1;
|
|
79
|
+
addTimer(timer, dataJson[watcherIdx].timer);
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
return dataJson;
|
|
84
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { map, throttleTime, of, timeout } from "rxjs";
|
|
2
|
+
import { Axios } from 'axios-observable';
|
|
3
|
+
import { insertHistory } from "./watcherController.js";
|
|
4
|
+
|
|
5
|
+
// let BIZA_SERVER_LINK;
|
|
6
|
+
|
|
7
|
+
// // if ((process.env.NODE_ENV == undefined) || (process.env.NODE_ENV == 'development')) {
|
|
8
|
+
// if ((MODE == undefined) || (MODE == 'development')) {
|
|
9
|
+
// BIZA_SERVER_LINK = envDev.BIZA_SERVER_LINK;
|
|
10
|
+
// } else {
|
|
11
|
+
// BIZA_SERVER_LINK = env.BIZA_SERVER_LINK;
|
|
12
|
+
// };
|
|
13
|
+
|
|
14
|
+
function mapData2Key(res, cols) {
|
|
15
|
+
return res.map(e => {
|
|
16
|
+
return cols.reduce((o, k) => {
|
|
17
|
+
o[k.key ? k.key : k.data] = e[k.data]
|
|
18
|
+
return o;
|
|
19
|
+
}, {})
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function hex2a(hexx) {
|
|
24
|
+
let hex = hexx.toString();//force conversion
|
|
25
|
+
let str = '';
|
|
26
|
+
for (let i = 0; i < hex.length; i += 2)
|
|
27
|
+
str += String.fromCharCode(parseInt(hex.slice(i, i + 2), 16));
|
|
28
|
+
return str;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function deserialise(key, data) {
|
|
32
|
+
if (data instanceof Array && data[0] == 'window.Function') {
|
|
33
|
+
let f = Function(data[1], data[2].join("\r\n"));
|
|
34
|
+
return f;
|
|
35
|
+
} else {
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function getUrlApi(config, methodName, isPost = true) {
|
|
41
|
+
return `${config.API_URL}/fina/rest/TOrmMethod/` +
|
|
42
|
+
`${isPost ? '%22' : ''}${methodName}${isPost ? '%22' : ''}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function json2Parameters(obj) {
|
|
46
|
+
return JSON.stringify(
|
|
47
|
+
{
|
|
48
|
+
_parameters: obj.map((el) => JSON.stringify(el))
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getUrlAndParam(config, method, obj, path) {
|
|
54
|
+
return {
|
|
55
|
+
url: getUrlApi(config, path),
|
|
56
|
+
params: json2Parameters([
|
|
57
|
+
{
|
|
58
|
+
dbIndex: config.dbindex,
|
|
59
|
+
method: method,
|
|
60
|
+
object: obj
|
|
61
|
+
}
|
|
62
|
+
])
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// export function getSelectedCompConfig(companyName) {
|
|
67
|
+
// const url = `${BIZA_SERVER_LINK}/config/%22getSelectedCompConfig%22`;
|
|
68
|
+
// const param = { companyName };
|
|
69
|
+
|
|
70
|
+
// return Axios.post(url, param).pipe(
|
|
71
|
+
// map(res => res.data?.data ? JSON.parse(res.data.data) : res.data)
|
|
72
|
+
// )
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
export function queryData(param, apiConfig, mapField) {
|
|
76
|
+
const defaultParam = {
|
|
77
|
+
start: 0, length: -1, order: [], filter: [], columns: []
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const { url, params } = getUrlAndParam(
|
|
81
|
+
apiConfig,
|
|
82
|
+
'list',
|
|
83
|
+
{ ...defaultParam, ...param },
|
|
84
|
+
'list'
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const options = {
|
|
88
|
+
headers: { 'content-type': 'text/plain' },
|
|
89
|
+
params: { subdomain: apiConfig.subdomain }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return Axios.post(url, params, options).pipe(
|
|
93
|
+
// tap(res=>console.log(res, 'res')),
|
|
94
|
+
map(res => res.data?.data ? JSON.parse(res.data.data) : res.data),
|
|
95
|
+
map(res => {
|
|
96
|
+
if (!mapField || res.error) return res;
|
|
97
|
+
return mapData2Key(res, param.columns)
|
|
98
|
+
})
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function crudData(param, apiConfig, method, path) {
|
|
103
|
+
const { url, params } = getUrlAndParam(
|
|
104
|
+
apiConfig,
|
|
105
|
+
method,
|
|
106
|
+
{ ...param },
|
|
107
|
+
path
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const options = {
|
|
111
|
+
headers: { 'content-type': 'text/plain' },
|
|
112
|
+
params: { subdomain: apiConfig.subdomain }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return Axios.post(url, params, options).pipe(
|
|
116
|
+
map(res => res.data?.data ? JSON.parse(res.data.data) : res.data),
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function genId(apiConfig, genName) {
|
|
121
|
+
const url = `${getUrlApi(apiConfig, 'genId', false)}/${genName}/${apiConfig.dbindex}`;
|
|
122
|
+
const options = {
|
|
123
|
+
headers: { 'content-type': 'text/plain' },
|
|
124
|
+
params: { subdomain: apiConfig.subdomain }
|
|
125
|
+
}
|
|
126
|
+
return Axios.get(url, options).pipe(
|
|
127
|
+
map(res => res.data?.data ? JSON.parse(res.data.data) : res.data),
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function extractFunctionScript(data) {
|
|
132
|
+
if (data.error) {
|
|
133
|
+
console.log(data.error, 'error')
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
if (data.length == 0) return
|
|
137
|
+
let hex = JSON.parse(hex2a(data[0].template))
|
|
138
|
+
//sementara ke template dahulu
|
|
139
|
+
// let hex = JSON.parse(hex2a(data[0].script))
|
|
140
|
+
|
|
141
|
+
if (!hex.functions) return
|
|
142
|
+
return JSON.parse(JSON.stringify(hex.functions), deserialise)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function getQueryDataObsParameters(trigger) {
|
|
146
|
+
return {
|
|
147
|
+
length: 1,
|
|
148
|
+
// filter: [{ junction: '', column: 'FILENAME', operator: '=', value1: `'${trigger.filename}'` }],
|
|
149
|
+
filter: [{ junction: '', column: 'FILENAME', operator: '=', value1: `'cekUser.js'` }],
|
|
150
|
+
columns: [{ data: "TEMPLATE.TEMPLATE", key: 'template' }]
|
|
151
|
+
|
|
152
|
+
//sementara ke template dahulu
|
|
153
|
+
// filter: [{ junction: '', column: 'ID', operator: '=', value1: `${trigger.scriptId}` }],
|
|
154
|
+
// columns: [{ data: "SYS$CLI_SCRIPT.SCRIPT", key: 'script' }]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function queryDataObservable(config, trigger) {
|
|
159
|
+
let param = getQueryDataObsParameters(trigger);
|
|
160
|
+
|
|
161
|
+
return queryData(param, config, true);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function getConfig(config) {
|
|
165
|
+
return (Array.isArray(config)) ? config[0] : config;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function loadCliScript(selectedConfig, trigger) {
|
|
169
|
+
const config = getConfig(selectedConfig);
|
|
170
|
+
|
|
171
|
+
return queryDataObservable(config, trigger).pipe(
|
|
172
|
+
// throttleTime(100)
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function scheduleSubscription(config, data, trigger, needSetHistory, isTest = false) {
|
|
177
|
+
try {
|
|
178
|
+
let functions = extractFunctionScript(data);
|
|
179
|
+
if (!isTest) { // next, change isTest to test better
|
|
180
|
+
functions.onInit(config, trigger.data);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (needSetHistory) {
|
|
184
|
+
insertHistory(config, trigger._id, new Date());
|
|
185
|
+
console.log(`Run Recent Schedule : ${trigger.name}`);
|
|
186
|
+
} else {
|
|
187
|
+
console.log(`Run Schedule : ${trigger.name}`);
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(error);
|
|
191
|
+
throw new Error(error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function checkSchedule(selectedConfig, trigger, needSetHistory) {
|
|
196
|
+
loadCliScript(selectedConfig, trigger).subscribe({
|
|
197
|
+
next: data => scheduleSubscription(selectedConfig, data, trigger, needSetHistory),
|
|
198
|
+
error: error => console.log(error.response.data || error)
|
|
199
|
+
})
|
|
200
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { checkSchedule } from "./datalib.js"
|
|
2
|
+
import { getWatchers, getHistories } from "./watcherController.js";
|
|
3
|
+
import { isItTime, loopTimer } from "./watcherlib.js"
|
|
4
|
+
import { setInterval } from 'timers/promises';
|
|
5
|
+
import { getCompanyObjectId, getSelectedConfig } from "../scheduler/configController.js";
|
|
6
|
+
import { forkJoin } from 'rxjs';
|
|
7
|
+
import { historyRecordToJson, watcherRecordToJson } from "./converter.js";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
11
|
+
export const SCHEDULE_INTERVAL = 60000;
|
|
12
|
+
|
|
13
|
+
export function increaseInterval(latestRun) {
|
|
14
|
+
const addInterval = new Date(latestRun).getMilliseconds() + SCHEDULE_INTERVAL;
|
|
15
|
+
return new Date(latestRun).setMilliseconds(addInterval);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getSelectedData(data, field, compareData) {
|
|
19
|
+
return data.find(element => {
|
|
20
|
+
return element[field].toString() == compareData.toString();
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function executeHistory(config, timer, history, currentTime) {
|
|
25
|
+
let latestRun = new Date(history.latestRun);
|
|
26
|
+
|
|
27
|
+
while ((latestRun < currentTime) &&
|
|
28
|
+
((currentTime - latestRun) >= SCHEDULE_INTERVAL)) {
|
|
29
|
+
if (isItTime(timer, latestRun)) {
|
|
30
|
+
checkSchedule(config, timer, false);
|
|
31
|
+
await delay(1000);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
latestRun = increaseInterval(latestRun);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function runHistory(histories, config, watchers, now) {
|
|
39
|
+
const currentTime = new Date(now);
|
|
40
|
+
|
|
41
|
+
for (const watcher of watchers) {
|
|
42
|
+
for (const timer of watcher.timer) {
|
|
43
|
+
const history = getSelectedData(histories, 'timerObjectId', timer._id);
|
|
44
|
+
if (history) {
|
|
45
|
+
await executeHistory(config, timer, history, currentTime)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export const runScheduler = async (companyName) => {
|
|
53
|
+
await delay(30000);
|
|
54
|
+
|
|
55
|
+
const company = await getCompanyObjectId(companyName);
|
|
56
|
+
const config = await getSelectedConfig(company._id);
|
|
57
|
+
|
|
58
|
+
forkJoin([getHistories(config[0]), getWatchers(config[0])]).subscribe({
|
|
59
|
+
next: ([historyResult, watcherResult]) => {
|
|
60
|
+
|
|
61
|
+
const histories = historyRecordToJson(historyResult);
|
|
62
|
+
const watchers = watcherRecordToJson(watcherResult);
|
|
63
|
+
runHistory(histories, config[0], watchers, new Date());
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
for await (const startTime of setInterval(SCHEDULE_INTERVAL, Date.now())) {
|
|
69
|
+
// if ((now - startTime) > 1000)
|
|
70
|
+
// break;
|
|
71
|
+
|
|
72
|
+
getWatchers(config[0]).subscribe({
|
|
73
|
+
next: result => {
|
|
74
|
+
const watchers = watcherRecordToJson(result);
|
|
75
|
+
for (const watcher of watchers) {
|
|
76
|
+
loopTimer(watcher.timer, Date.now(), config[0], true);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// // reload == true ?
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { from, tap } from 'rxjs';
|
|
2
|
+
import { concatMap, map, catchError } from 'rxjs/operators';
|
|
3
|
+
|
|
4
|
+
import { crudData, genId, queryData } from '../scheduler/datalib.js';
|
|
5
|
+
|
|
6
|
+
//LIST
|
|
7
|
+
export function getWatcherParameters(watcherFilter) {
|
|
8
|
+
return {
|
|
9
|
+
// filter: [{ junction: '', column: 'COMPANY_OBJ_ID', operator: '=', value1: `'${watcherFilter?.companyObjectId}'` }],
|
|
10
|
+
columns: [
|
|
11
|
+
{ data: "SYS$WATCHER.ID", key: 'watcher_id' },
|
|
12
|
+
{ data: "SYS$WATCHER.COMPANY_OBJ_ID", key: 'company_id' },
|
|
13
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.ID", key: 'timer_id' },
|
|
14
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.WATCHER_ID", key: 'timer_watcher_id' },
|
|
15
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.NAME", key: 'name' },
|
|
16
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.ACTIVE", key: 'active' },
|
|
17
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.TIME_ZONE", key: 'timezone' },
|
|
18
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.SCRIPT_NAME", key: 'templateName' },
|
|
19
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.SEQ", key: 'seq' },
|
|
20
|
+
{ data: "SYS$WATCHER.ID.WATCHER_ID.SYS$TIMER.SCRIPT_ID", key: 'scriptId' },
|
|
21
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$DAILY.DAYS", key: 'daily_days' },
|
|
22
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$WEEKLY.ORDINAL", key: 'weekly_ordinal' },
|
|
23
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$WEEKLY.DAYS", key: 'weekly_days' },
|
|
24
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$MONTHLY.DAYS", key: 'monthly_days' },
|
|
25
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$MINUTELY.EVERYMIN", key: 'minutely_everymin' },
|
|
26
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$MINUTELY.TIME_FROM", key: 'minutely_time_from' },
|
|
27
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$MINUTELY.TIME_TO", key: 'minutely_time_to' },
|
|
28
|
+
{ data: "SYS$TIMER.ID.TIMER_ID.SYS$HOURLY.HOURS", key: 'hourly_hours' },
|
|
29
|
+
{ data: "SYS$TIMER.SCRIPT_ID.ID.SYS$CLI_SCRIPT.SCRIPT", key: 'cli_script' }
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getWatchers(config, watcherFilter) {
|
|
35
|
+
let param = getWatcherParameters(watcherFilter);
|
|
36
|
+
return queryData(param, config, true, 'list', 'list');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
//HISTORY
|
|
41
|
+
export function getInsertHistoryParameters(timerObjectId) {
|
|
42
|
+
return {
|
|
43
|
+
filter: [{
|
|
44
|
+
junction: '',
|
|
45
|
+
column: 'TIMER_ID',
|
|
46
|
+
operator: '=',
|
|
47
|
+
value1: `'${timerObjectId}'`
|
|
48
|
+
}],
|
|
49
|
+
columns: [
|
|
50
|
+
{ data: "HISTORY.ID", key: 'history_id' },
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function formatDate2API(oriDate) {
|
|
56
|
+
return oriDate.replace('T', ' ').replace('Z', '');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getHistoryField(timerObjectId, historyId, currentDate) {
|
|
60
|
+
return {
|
|
61
|
+
SYS$HISTORY: {
|
|
62
|
+
ID: historyId,
|
|
63
|
+
TIMER_ID: parseInt(timerObjectId),
|
|
64
|
+
LATEST_RUN: formatDate2API(new Date(currentDate).toISOString())
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function insertHistory(config, timerObjectId, currentDate) {
|
|
70
|
+
const listData = getInsertHistoryParameters(timerObjectId);
|
|
71
|
+
|
|
72
|
+
queryData(listData, config, true, 'list', 'list')
|
|
73
|
+
// return queryData(listData, config, true, 'list', 'list')
|
|
74
|
+
.pipe(
|
|
75
|
+
concatMap(historyResponse => {
|
|
76
|
+
const history = historyResponse[0];
|
|
77
|
+
|
|
78
|
+
return history ? from([parseInt(history.history_id)]) : genId(config, 'SYS$HISTORY_ID_GEN');
|
|
79
|
+
}),
|
|
80
|
+
map(historyId => {
|
|
81
|
+
return getHistoryField(timerObjectId, historyId, currentDate);
|
|
82
|
+
}),
|
|
83
|
+
concatMap(param => crudData(param, config, 'put', 'orm')),
|
|
84
|
+
catchError(error => {
|
|
85
|
+
console.error(error);
|
|
86
|
+
return new Error(error);
|
|
87
|
+
})
|
|
88
|
+
// )
|
|
89
|
+
).subscribe();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function getHistoryParameters(timerObjectId) {
|
|
93
|
+
return {
|
|
94
|
+
columns: [
|
|
95
|
+
{ data: "SYS$HISTORY.ID", key: 'history_id' },
|
|
96
|
+
{ data: "SYS$HISTORY.TIMER_ID", key: 'timer_id' },
|
|
97
|
+
{ data: "SYS$HISTORY.LATEST_RUN", key: 'latest_run' }
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function getHistories(config, timerObjectId) {
|
|
103
|
+
let param = getHistoryParameters(timerObjectId);
|
|
104
|
+
return queryData(param, config, true, 'list', 'list');
|
|
105
|
+
}
|