mirror of https://git.48k.eu/ogserver
#915 Add commands and procedures to procedure creation
Adds the possibility to create a procedure with commands and other procedures integrated as steps. Note: "steps" parameter is optional and "steps" array object order defines execution order. Request: POST /procedure/add { "center": "1", "name": "procedure", "description": "My procedure", "steps": [ { "command": "wol", "params": { "type": "broadcast" } }, { "procedure": 22 }, { "command": "poweroff", "params": {} } ] } Response: 200 OK This commit also updates unit tests for /procedure/add POST method to include steps.master
parent
893101ffc6
commit
1fdb7e6d1c
72
src/json.c
72
src/json.c
|
@ -140,3 +140,75 @@ int og_json_parse_partition(json_t *element, struct og_partition *part,
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int og_json_parse_procedure_cmd(json_t *element, int position,
|
||||||
|
struct og_procedure *proc)
|
||||||
|
{
|
||||||
|
struct og_procedure_step *step;
|
||||||
|
uint32_t err = 0;
|
||||||
|
const char *key;
|
||||||
|
json_t *value;
|
||||||
|
|
||||||
|
step = &proc->steps[proc->num_steps++];
|
||||||
|
step->type = OG_STEP_COMMAND;
|
||||||
|
step->position = position;
|
||||||
|
|
||||||
|
json_object_foreach(element, key, value) {
|
||||||
|
if (!strcmp(key, "command"))
|
||||||
|
err = og_json_parse_string(value, &step->cmd.type);
|
||||||
|
else if (!strcmp(key, "params"))
|
||||||
|
step->cmd.json = value;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int og_json_parse_procedure_call(json_t *element, int position,
|
||||||
|
struct og_procedure *proc)
|
||||||
|
{
|
||||||
|
struct og_procedure_step *step;
|
||||||
|
uint32_t err = 0;
|
||||||
|
const char *key;
|
||||||
|
json_t *value;
|
||||||
|
|
||||||
|
step = &proc->steps[proc->num_steps++];
|
||||||
|
step->type = OG_STEP_PROCEDURE;
|
||||||
|
step->position = position;
|
||||||
|
|
||||||
|
json_object_foreach(element, key, value) {
|
||||||
|
if (!strcmp(key, "procedure"))
|
||||||
|
err = og_json_parse_uint64(value, &step->procedure.id);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int og_json_parse_procedure(json_t *element, struct og_procedure *proc)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
json_t *item;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (json_typeof(element) != JSON_ARRAY)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < json_array_size(element) && i < OG_PROCEDURE_STEPS_MAX; ++i) {
|
||||||
|
item = json_array_get(element, i);
|
||||||
|
|
||||||
|
if (json_object_get(item, "command"))
|
||||||
|
err = og_json_parse_procedure_cmd(item, i, proc);
|
||||||
|
else if (json_object_get(item, "procedure"))
|
||||||
|
err = og_json_parse_procedure_call(item, i, proc);
|
||||||
|
else
|
||||||
|
err = -1;
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
27
src/json.h
27
src/json.h
|
@ -98,4 +98,31 @@ struct og_cmd_json {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum og_procedure_step_type {
|
||||||
|
OG_STEP_COMMAND = 0,
|
||||||
|
OG_STEP_PROCEDURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OG_PROCEDURE_STEPS_MAX 256
|
||||||
|
|
||||||
|
struct og_procedure_step {
|
||||||
|
enum og_procedure_step_type type;
|
||||||
|
uint32_t position;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct og_cmd_json cmd;
|
||||||
|
struct {
|
||||||
|
uint64_t id;
|
||||||
|
} procedure;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct og_procedure {
|
||||||
|
uint64_t id;
|
||||||
|
struct og_procedure_step steps[OG_PROCEDURE_STEPS_MAX];
|
||||||
|
uint32_t num_steps;
|
||||||
|
};
|
||||||
|
|
||||||
|
int og_json_parse_procedure(json_t *element, struct og_procedure *proc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
76
src/rest.c
76
src/rest.c
|
@ -4076,9 +4076,72 @@ static int og_cmd_post_center_delete(json_t *element,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int og_procedure_add_steps(struct og_dbi *dbi, struct og_procedure *proc)
|
||||||
|
{
|
||||||
|
struct og_procedure_step *step;
|
||||||
|
uint64_t procedure = 0;
|
||||||
|
const char *legacy_params;
|
||||||
|
const char *msglog;
|
||||||
|
dbi_result result;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < proc->num_steps; i++) {
|
||||||
|
step = &proc->steps[i];
|
||||||
|
switch (step->type) {
|
||||||
|
case OG_STEP_COMMAND:
|
||||||
|
legacy_params = og_msg_params_to_legacy(&step->cmd);
|
||||||
|
if (!legacy_params) {
|
||||||
|
og_dbi_close(dbi);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
|
"INSERT INTO procedimientos_acciones "
|
||||||
|
"(idprocedimiento, orden, parametros) "
|
||||||
|
"VALUES (%d, %d, '%s')",
|
||||||
|
procedure,
|
||||||
|
step->position,
|
||||||
|
legacy_params);
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"failed to add procedure command to database (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
og_dbi_close(dbi);
|
||||||
|
free((char *)legacy_params);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbi_result_free(result);
|
||||||
|
free((char *)legacy_params);
|
||||||
|
break;
|
||||||
|
case OG_STEP_PROCEDURE:
|
||||||
|
result = dbi_conn_queryf(dbi->conn,
|
||||||
|
"INSERT INTO procedimientos_acciones "
|
||||||
|
"(idprocedimiento, orden, procedimientoid) "
|
||||||
|
"VALUES (%d, %d, %d)",
|
||||||
|
procedure,
|
||||||
|
step->position,
|
||||||
|
step->procedure.id);
|
||||||
|
if (!result) {
|
||||||
|
dbi_conn_error(dbi->conn, &msglog);
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"failed to add procedure child to database (%s:%d) %s\n",
|
||||||
|
__func__, __LINE__, msglog);
|
||||||
|
og_dbi_close(dbi);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dbi_result_free(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int og_cmd_post_procedure_add(json_t *element,
|
static int og_cmd_post_procedure_add(json_t *element,
|
||||||
struct og_msg_params *params)
|
struct og_msg_params *params)
|
||||||
{
|
{
|
||||||
|
struct og_procedure proc = {};
|
||||||
const char *key, *msglog;
|
const char *key, *msglog;
|
||||||
struct og_dbi *dbi;
|
struct og_dbi *dbi;
|
||||||
dbi_result result;
|
dbi_result result;
|
||||||
|
@ -4092,8 +4155,11 @@ static int og_cmd_post_procedure_add(json_t *element,
|
||||||
} else if (!strcmp(key, "name")) {
|
} else if (!strcmp(key, "name")) {
|
||||||
err = og_json_parse_string(value, ¶ms->name);
|
err = og_json_parse_string(value, ¶ms->name);
|
||||||
params->flags |= OG_REST_PARAM_NAME;
|
params->flags |= OG_REST_PARAM_NAME;
|
||||||
} else if (!strcmp(key, "description"))
|
} else if (!strcmp(key, "description")) {
|
||||||
err = og_json_parse_string(value, ¶ms->comment);
|
err = og_json_parse_string(value, ¶ms->comment);
|
||||||
|
} else if (!strcmp(key, "steps")) {
|
||||||
|
err = og_json_parse_procedure(value, &proc);
|
||||||
|
}
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -4147,10 +4213,14 @@ static int og_cmd_post_procedure_add(json_t *element,
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbi_result_free(result);
|
dbi_result_free(result);
|
||||||
|
|
||||||
|
proc.id = dbi_conn_sequence_last(dbi->conn, NULL);
|
||||||
|
err = og_procedure_add_steps(dbi, &proc);
|
||||||
|
|
||||||
og_dbi_close(dbi);
|
og_dbi_close(dbi);
|
||||||
return 0;
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int og_cmd_post_room_add(json_t *element,
|
static int og_cmd_post_room_add(json_t *element,
|
||||||
|
|
|
@ -8,7 +8,10 @@ class TestPostProcedureAddMethods(unittest.TestCase):
|
||||||
self.headers = {'Authorization' : '07b3bfe728954619b58f0107ad73acc1'}
|
self.headers = {'Authorization' : '07b3bfe728954619b58f0107ad73acc1'}
|
||||||
self.full_json = { "center": "1",
|
self.full_json = { "center": "1",
|
||||||
"name": "procedure1",
|
"name": "procedure1",
|
||||||
"description": "procedure test" }
|
"description": "procedure test",
|
||||||
|
"steps": [ { "command": "wol",
|
||||||
|
"params": { "type": "broadcast" } },
|
||||||
|
{ "procedure": 22 } ] }
|
||||||
self.minimal_json = { "center": "1",
|
self.minimal_json = { "center": "1",
|
||||||
"name": "procedure2" }
|
"name": "procedure2" }
|
||||||
self.duplicated_procedure_json = { "center": "1",
|
self.duplicated_procedure_json = { "center": "1",
|
||||||
|
|
Loading…
Reference in New Issue