Use json_is_true() in place of json_boolean_value() for compatibility
[trust_router.git] / mon / mon_req_encode.c
1 /*
2  * Copyright (c) 2018, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34
35
36 #include <talloc.h>
37 #include <jansson.h>
38 #include <glib.h>
39
40 #include <mon_internal.h>
41
42 /* Monitoring request encoders */
43
44 /**
45  * Encode options array as a JSON array
46  *
47  * Format:
48  * [
49  *   { "type": "first_type" },
50  *   { "type": "second_type"},
51  *   ...
52  * ]
53  *
54  * @param opts array of options
55  * @return reference to a JSON array of options
56  */
57 static json_t *mon_opts_encode(GArray *opts)
58 {
59   json_t *array_json = json_array(); // the array of options
60   json_t *opt_json = NULL; // individual option JSON object
61   json_t *type_json = NULL;
62   guint ii = 0;
63   MON_OPT this_opt;
64
65   if (array_json == NULL)
66     return NULL; // failed
67
68   /* Iterate over the options */
69   for (ii=0; ii < opts->len; ii++) {
70     this_opt = g_array_index(opts, MON_OPT, ii);
71
72     /* Create the JSON object for this option */
73     opt_json = json_object();
74     if (opt_json == NULL) {
75       json_decref(array_json);
76       return NULL;
77     }
78
79     /* Add to the array, making opt_json a borrowed ref if we succeed */
80     if (json_array_append_new(array_json, opt_json) == -1) {
81       json_decref(array_json);
82       json_decref(opt_json); // handle ourselves because the set failed
83     }
84
85     /* Create the type string for this option */
86     type_json = json_string(mon_opt_type_to_string(this_opt.type));
87     if (type_json == NULL) {
88       json_decref(array_json);
89       return NULL;
90     }
91
92     /* Add the type string to the JSON object, making type_json a borrowed ref */
93     if (json_object_set_new(opt_json, "type", type_json) == -1) {
94       json_decref(array_json);
95       json_decref(type_json); // must handle ourselves because the set failed
96       return NULL;
97     }
98   }
99
100   return array_json;
101 }
102
103 /**
104  * Encode a request as a JSON object
105  *
106  * Caller must free the return value using json_decref()
107  *
108  * Format:
109  * {
110  *   "command": "some_command",
111  *   "options": [...see mon_opts_to_json()...]
112  * }
113  *
114  * @param req request to encode
115  * @return reference to a JSON object
116  */
117 json_t *mon_req_encode(MON_REQ *req)
118 {
119   json_t *req_json = NULL;
120   json_t *cmd_json = NULL;
121   json_t *opts_json = NULL;
122
123   /* Allocate the base JSON object */
124   req_json = json_object();
125   if (req_json == NULL)
126     return NULL;
127
128   /* Allocate the JSON string for the command */
129   cmd_json = json_string(mon_cmd_to_string(req->command));
130   if (cmd_json == NULL) {
131     json_decref(req_json);
132     return NULL;
133   }
134
135   /* Add the command string to the base object. Steals the reference to
136    * the string if successful. */
137   if (json_object_set_new(req_json, "command", cmd_json) == -1) {
138     json_decref(cmd_json); // must clean this up ourselves because the set failed
139     json_decref(req_json);
140     return NULL;
141   }
142
143   /* If we have options, add them to the object */
144   if (req->options->len > 0) {
145     opts_json = mon_opts_encode(req->options);
146     if (opts_json == NULL) {
147       json_decref(req_json);
148       return NULL;
149     }
150
151     if (json_object_set_new(req_json, "options", opts_json) == -1) {
152       json_decref(req_json);
153       json_decref(opts_json); // must clean this up ourselves because set failed
154       return NULL;
155     }
156   }
157
158   /* That's it, we succeeded */
159   return req_json;
160 }
161