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;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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
|
||||
|
|
76
src/rest.c
76
src/rest.c
|
@ -4076,9 +4076,72 @@ static int og_cmd_post_center_delete(json_t *element,
|
|||
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,
|
||||
struct og_msg_params *params)
|
||||
{
|
||||
struct og_procedure proc = {};
|
||||
const char *key, *msglog;
|
||||
struct og_dbi *dbi;
|
||||
dbi_result result;
|
||||
|
@ -4092,8 +4155,11 @@ static int og_cmd_post_procedure_add(json_t *element,
|
|||
} else if (!strcmp(key, "name")) {
|
||||
err = og_json_parse_string(value, ¶ms->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);
|
||||
} else if (!strcmp(key, "steps")) {
|
||||
err = og_json_parse_procedure(value, &proc);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -4147,10 +4213,14 @@ static int og_cmd_post_procedure_add(json_t *element,
|
|||
og_dbi_close(dbi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbi_result_free(result);
|
||||
|
||||
proc.id = dbi_conn_sequence_last(dbi->conn, NULL);
|
||||
err = og_procedure_add_steps(dbi, &proc);
|
||||
|
||||
og_dbi_close(dbi);
|
||||
return 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int og_cmd_post_room_add(json_t *element,
|
||||
|
|
|
@ -8,7 +8,10 @@ class TestPostProcedureAddMethods(unittest.TestCase):
|
|||
self.headers = {'Authorization' : '07b3bfe728954619b58f0107ad73acc1'}
|
||||
self.full_json = { "center": "1",
|
||||
"name": "procedure1",
|
||||
"description": "procedure test" }
|
||||
"description": "procedure test",
|
||||
"steps": [ { "command": "wol",
|
||||
"params": { "type": "broadcast" } },
|
||||
{ "procedure": 22 } ] }
|
||||
self.minimal_json = { "center": "1",
|
||||
"name": "procedure2" }
|
||||
self.duplicated_procedure_json = { "center": "1",
|
||||
|
|
Loading…
Reference in New Issue