summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Sánchez Parra <jsanchez@soleta.eu>2021-06-04 12:46:15 +0200
committerOpenGnSys Support Team <soporte-og@soleta.eu>2021-06-10 17:00:01 +0200
commit1fdb7e6d1cf0709b1079b2d9990c0d53d8740461 (patch)
treee13f19f28e2ee379150171bad00fecec59168901
parent893101ffc6162d64cfbe5827c32d4e6de5e35f42 (diff)
#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.
-rw-r--r--src/json.c72
-rw-r--r--src/json.h27
-rw-r--r--src/rest.c76
-rw-r--r--tests/units/test_0033_post_procedure_add.py5
4 files changed, 176 insertions, 4 deletions
diff --git a/src/json.c b/src/json.c
index a2b300f..3765782 100644
--- a/src/json.c
+++ b/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;
+}
diff --git a/src/json.h b/src/json.h
index 08a78d0..0e98a6e 100644
--- a/src/json.h
+++ b/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
diff --git a/src/rest.c b/src/rest.c
index feeb306..9c5d934 100644
--- a/src/rest.c
+++ b/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, &params->name);
params->flags |= OG_REST_PARAM_NAME;
- } else if (!strcmp(key, "description"))
+ } else if (!strcmp(key, "description")) {
err = og_json_parse_string(value, &params->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,
diff --git a/tests/units/test_0033_post_procedure_add.py b/tests/units/test_0033_post_procedure_add.py
index b31ac70..89a21c7 100644
--- a/tests/units/test_0033_post_procedure_add.py
+++ b/tests/units/test_0033_post_procedure_add.py
@@ -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",