implement flows runtime stop/start API and UI

This commit is contained in:
Steve-Mcl
2022-06-08 21:56:17 +01:00
parent 62cd3b2061
commit 68331fc40c
18 changed files with 657 additions and 63 deletions

View File

@@ -73,6 +73,10 @@ var api = module.exports = {
if (deploymentType === 'reload') {
apiPromise = runtime.flows.loadFlows(true);
} else {
//ensure the runtime running/stopped state matches the deploying editor. If not, then copy the _rev number to flows.rev
if(flows.hasOwnProperty('_rev') && !flows.hasOwnProperty('rev') && (flows.runtimeState !== "stopped" || runtime.flows.started)) {
flows.rev = flows._rev
}
if (flows.hasOwnProperty('rev')) {
var currentVersion = runtime.flows.getFlows().rev;
if (currentVersion !== flows.rev) {
@@ -255,5 +259,83 @@ var api = module.exports = {
}
}
return sendCredentials;
}
},
/**
* Gets running state of runtime flows
* @param {Object} opts
* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {{state:string, started:boolean}} - the current run state of the flows
* @memberof @node-red/runtime_flows
*/
getState: async function(opts) {
runtime.log.audit({event: "flows.getState"}, opts.req);
const result = {
state: runtime.flows.started ? "started" : "stopped",
started: !!runtime.flows.started,
rev: runtime.flows.getFlows().rev
}
return result;
},
/**
* Sets running state of runtime flows
* @param {Object} opts
* @param {Object} opts.req - the request to log (optional)
* @param {User} opts.user - the user calling the api
* @param {string} opts.requestedState - the requested state. Valid values are "start" and "stop".
* @return {Promise<Flow>} - the active flow configuration
* @memberof @node-red/runtime_flows
*/
setState: async function(opts) {
opts = opts || {};
const makeError = (error, errcode, statusCode) => {
const message = typeof error == "object" ? error.message : error
const err = typeof error == "object" ? error : new Error(message||"Unexpected Error")
err.status = err.status || statusCode || 400;
err.code = err.code || errcode || "unexpected_error"
runtime.log.audit({
event: "flows.setState",
state: opts.requestedState || "",
error: errcode || "unexpected_error",
message: err.code
}, opts.req);
return err
}
const getState = () => {
return {
state: runtime.flows.started ? "started" : "stopped",
started: !!runtime.flows.started,
rev: runtime.flows.getFlows().rev,
}
}
if(runtime.settings.runtimeState ? runtime.settings.runtimeState.enabled === false : false) {
throw (makeError("Method Not Allowed", "not_allowed", 405))
}
switch (opts.requestedState) {
case "start":
try {
try {
runtime.settings.set('flowsRunStateRequested', opts.requestedState);
} catch(err) { }
await runtime.flows.startFlows("full")
return getState()
} catch (err) {
throw (makeError(err, err.code, 500))
}
case "stop":
try {
try {
runtime.settings.set('flowsRunStateRequested', opts.requestedState);
} catch(err) { }
await runtime.flows.stopFlows("full")
return getState()
} catch (err) {
throw (makeError(err, err.code, 500))
}
default:
throw (makeError("Cannot set runtime state. Invalid state", "invalid_run_state", 400))
}
},
}

View File

@@ -148,6 +148,18 @@ var api = module.exports = {
enabled: (runtime.settings.diagnostics && runtime.settings.diagnostics.enabled === false) ? false : true,
ui: (runtime.settings.diagnostics && runtime.settings.diagnostics.ui === false) ? false : true
}
if(safeSettings.diagnostics.enabled === false) {
safeSettings.diagnostics.ui = false; // cannot have UI without endpoint
}
safeSettings.runtimeState = {
//unless runtimeState.ui and runtimeState.enabled are explicitly false, they will default to true.
enabled: (runtime.settings.runtimeState && runtime.settings.runtimeState.enabled === false) ? false : true,
ui: (runtime.settings.runtimeState && runtime.settings.runtimeState.ui === false) ? false : true
}
if(safeSettings.runtimeState.enabled === false) {
safeSettings.runtimeState.ui = false; // cannot have UI without endpoint
}
runtime.settings.exportNodeSettings(safeSettings);
runtime.plugins.exportPluginSettings(safeSettings);