Skip to content
This repository was archived by the owner on Dec 26, 2022. It is now read-only.

Commit bee44ef

Browse files
committed
feat(api): Read setting from configuration file
1 parent b073b8c commit bee44ef

File tree

7 files changed

+188
-10
lines changed

7 files changed

+188
-10
lines changed

accelerator/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ cc_library(
123123
"//utils:cache",
124124
"//utils:pow",
125125
"@entangled//cclient/api",
126+
"@yaml",
126127
],
127128
)
128129

accelerator/config.c

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,22 @@
99
#include "config.h"
1010
#include "utils/logger_helper.h"
1111
#include "utils/macros.h"
12+
#include "yaml.h"
1213

1314
#define CONFIG_LOGGER "TA"
1415

1516
static logger_id_t config_logger_id;
1617

18+
int get_conf_key(char const* const key) {
19+
for (int i = 0; i < cli_cmd_num; ++i) {
20+
if (!strcmp(ta_cli_arguments_g[i].name, key)) {
21+
return ta_cli_arguments_g[i].val;
22+
}
23+
}
24+
25+
return 0;
26+
}
27+
1728
struct option* cli_build_options() {
1829
struct option* long_options = (struct option*)malloc(cli_cmd_num * sizeof(struct option));
1930
for (int i = 0; i < cli_cmd_num; ++i) {
@@ -25,12 +36,13 @@ struct option* cli_build_options() {
2536
return long_options;
2637
}
2738

28-
status_t cli_config_set(ta_config_t* const info, iota_config_t* const iconf, ta_cache_t* const cache,
39+
status_t cli_config_set(char* conf_file, ta_config_t* const info, iota_config_t* const iconf, ta_cache_t* const cache,
2940
iota_client_service_t* const service, int key, char* const value) {
3041
if (value == NULL || info == NULL || iconf == NULL || cache == NULL || service == NULL) {
3142
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_NULL");
3243
return SC_CONF_NULL;
3344
}
45+
3446
switch (key) {
3547
// TA configuration
3648
case TA_HOST_CLI:
@@ -70,7 +82,21 @@ status_t cli_config_set(ta_config_t* const info, iota_config_t* const iconf, ta_
7082
iconf->seed = value;
7183
break;
7284
case CACHE:
73-
cache->cache_state = !(strncmp(value, "T", 1));
85+
cache->cache_state = (toupper(value[0]) == 'T');
86+
break;
87+
88+
// Verbose configuration
89+
case VERBOSE:
90+
verbose_mode = (toupper(value[0]) == 'T');
91+
break;
92+
93+
// File configuration
94+
case CONF_CLI: {
95+
size_t arg_len = strlen(value);
96+
strncpy(conf_file, value, arg_len);
97+
conf_file[arg_len] = '\0';
98+
break;
99+
}
74100
}
75101
return SC_OK;
76102
}
@@ -122,6 +148,108 @@ status_t ta_config_default_init(ta_config_t* const info, iota_config_t* const ic
122148
return ret;
123149
}
124150

151+
status_t ta_config_file_init(ta_core_t* const conf, int argc, char** argv) {
152+
int key = 0;
153+
status_t ret = SC_OK;
154+
struct option* long_options = cli_build_options();
155+
yaml_parser_t parser;
156+
yaml_token_t token;
157+
FILE* file = NULL;
158+
char* arg = NULL;
159+
int state = 0;
160+
161+
// Initialize default configuration file path with '\0'
162+
conf->conf_file[0] = '\0';
163+
164+
if (!yaml_parser_initialize(&parser)) {
165+
ret = SC_CONF_PARSER_ERROR;
166+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_PARSER_ERROR");
167+
goto done;
168+
}
169+
170+
// Loop through the CLI arguments for first time to find the configuration file path
171+
while ((key = getopt_long(argc, argv, "hv", long_options, NULL)) != -1) {
172+
switch (key) {
173+
case ':':
174+
ret = SC_CONF_MISSING_ARGUMENT;
175+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_MISSING_ARGUMENT");
176+
break;
177+
case '?':
178+
ret = SC_CONF_UNKNOWN_OPTION;
179+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_UNKNOWN_OPTION");
180+
break;
181+
case CONF_CLI:
182+
ret = cli_config_set(conf->conf_file, &conf->info, &conf->iconf, &conf->cache, &conf->service, key, optarg);
183+
break;
184+
default:
185+
break;
186+
}
187+
if (ret != SC_OK) {
188+
break;
189+
}
190+
}
191+
192+
// Reset the CLI option index for the second loop where they are actually analyzed
193+
optind = 1;
194+
195+
if (strlen(conf->conf_file) == 0) {
196+
/* No configuration file specified */
197+
ret = SC_OK;
198+
goto done;
199+
}
200+
201+
if ((file = fopen(conf->conf_file, "r")) == NULL) {
202+
/* The specified configuration file does not exist */
203+
ret = SC_CONF_FOPEN_ERROR;
204+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_FOPEN_ERROR");
205+
goto done;
206+
}
207+
208+
yaml_parser_set_input_file(&parser, file);
209+
210+
do { /* start reading tokens */
211+
if (!yaml_parser_scan(&parser, &token)) {
212+
ret = SC_CONF_PARSER_ERROR;
213+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_PARSER_ERROR");
214+
goto done;
215+
}
216+
switch (token.type) {
217+
case YAML_KEY_TOKEN:
218+
state = 0;
219+
break;
220+
case YAML_VALUE_TOKEN:
221+
state = 1;
222+
break;
223+
case YAML_SCALAR_TOKEN:
224+
arg = (char*)token.data.scalar.value;
225+
if (state == 0) { // Key
226+
key = get_conf_key(arg);
227+
} else { // Value
228+
if ((ret = cli_config_set(conf->conf_file, &conf->info, &conf->iconf, &conf->cache, &conf->service, key,
229+
strdup(arg))) != SC_OK) {
230+
goto done;
231+
}
232+
}
233+
break;
234+
default:
235+
break;
236+
}
237+
if (token.type != YAML_STREAM_END_TOKEN) {
238+
yaml_token_delete(&token);
239+
}
240+
} while (token.type != YAML_STREAM_END_TOKEN);
241+
242+
done:
243+
yaml_token_delete(&token);
244+
yaml_parser_delete(&parser);
245+
if (file) {
246+
fclose(file);
247+
}
248+
free(long_options);
249+
250+
return ret;
251+
}
252+
125253
status_t ta_config_cli_init(ta_core_t* const conf, int argc, char** argv) {
126254
int key = 0;
127255
status_t ret = SC_OK;
@@ -131,9 +259,11 @@ status_t ta_config_cli_init(ta_core_t* const conf, int argc, char** argv) {
131259
switch (key) {
132260
case ':':
133261
ret = SC_CONF_MISSING_ARGUMENT;
262+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_MISSING_ARGUMENT");
134263
break;
135264
case '?':
136265
ret = SC_CONF_UNKNOWN_OPTION;
266+
log_error(config_logger_id, "[%s:%d:%s]\n", __func__, __LINE__, "SC_CONF_UNKNOWN_OPTION");
137267
break;
138268
case 'h':
139269
ta_usage();
@@ -148,8 +278,11 @@ status_t ta_config_cli_init(ta_core_t* const conf, int argc, char** argv) {
148278
// Enable backend_redis logger
149279
br_logger_init();
150280
break;
281+
case CONF_CLI:
282+
/* Already processed in ta_config_file_init() */
283+
break;
151284
default:
152-
ret = cli_config_set(&conf->info, &conf->iconf, &conf->cache, &conf->service, key, optarg);
285+
ret = cli_config_set(conf->conf_file, &conf->info, &conf->iconf, &conf->cache, &conf->service, key, optarg);
153286
break;
154287
}
155288
if (ret != SC_OK) {

accelerator/config.h

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef ACCELERATOR_CONFIG_H_
1010
#define ACCELERATOR_CONFIG_H_
1111

12+
#include <ctype.h>
1213
#include <getopt.h>
1314

1415
#include "accelerator/message.h"
@@ -17,6 +18,8 @@
1718
#include "utils/cache.h"
1819
#include "utils/pow.h"
1920

21+
#define FILE_PATH_SIZE 128
22+
2023
#ifdef __cplusplus
2124
extern "C" {
2225
#endif
@@ -82,15 +85,28 @@ typedef struct ta_cache_s {
8285

8386
/** struct type of accelerator core */
8487
typedef struct ta_core_s {
85-
ta_config_t info; /**< accelerator configiuration structure */
86-
ta_cache_t cache; /**< redis configiuration structure */
87-
iota_config_t iconf; /**< iota configuration structure */
88-
iota_client_service_t service; /**< iota connection structure */
88+
ta_config_t info; /**< accelerator configiuration structure */
89+
ta_cache_t cache; /**< redis configiuration structure */
90+
iota_config_t iconf; /**< iota configuration structure */
91+
iota_client_service_t service; /**< iota connection structure */
92+
char conf_file[FILE_PATH_SIZE]; /**< path to the configuration file */
8993
} ta_core_t;
9094

95+
/**
96+
* @brief Get corresponding key-value pair in ta_cli_arguments_g structure
97+
* key : correspond to "name" in ta_cli_arguments_g structure
98+
* value : correspond to "val" in ta_cli_arguments_g structure
99+
*
100+
* @param key[in] Key of the key-value pair in yaml file
101+
*
102+
* @return
103+
* - ZERO on Parsing unknown key
104+
* - non-zero Corresponding value of key
105+
*/
106+
int get_conf_key(char const* const key);
107+
91108
/**
92109
* Initializes configurations with default values
93-
* Should be called first
94110
*
95111
* @param info[in] Tangle-accelerator configuration variables
96112
* @param tangle[in] iota configuration variables
@@ -104,12 +120,24 @@ typedef struct ta_core_s {
104120
status_t ta_config_default_init(ta_config_t* const info, iota_config_t* const tangle, ta_cache_t* const cache,
105121
iota_client_service_t* const service);
106122

123+
/**
124+
* Initializes configurations with configuration file
125+
*
126+
* @param ta_conf[in] All configuration variables
127+
* @param argc[in] Number of argument of CLI
128+
* @param argv[in] Argument of CLI
129+
*
130+
* @return
131+
* - SC_OK on success
132+
* - non-zero on error
133+
*/
134+
status_t ta_config_file_init(ta_core_t* const ta_conf, int argc, char** argv);
135+
107136
/**
108137
* Initializes configurations with CLI values
109-
* Should be called third
110138
*
111139
* @param ta_conf[in] All configuration variables
112-
* @param argc[in] Number of argumentof CLI
140+
* @param argc[in] Number of argument of CLI
113141
* @param argv[in] Argument of CLI
114142
*
115143
* @return

accelerator/errors.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ typedef enum {
158158
/**< fail to init lock */
159159
SC_CONF_LOCK_DESTROY = 0x05 | SC_MODULE_CONF | SC_SEVERITY_FATAL,
160160
/**< fail to destroy lock */
161+
SC_CONF_PARSER_ERROR = 0x06 | SC_MODULE_CONF | SC_SEVERITY_FATAL,
162+
/**< fail to initialize yaml parser */
163+
SC_CONF_FOPEN_ERROR = 0x07 | SC_MODULE_CONF | SC_SEVERITY_FATAL,
164+
/**< fail to open file */
161165

162166
// UTILS module
163167
SC_UTILS_NULL = 0x01 | SC_MODULE_UTILS | SC_SEVERITY_FATAL,

accelerator/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ int main(int argc, char* argv[]) {
3232
return EXIT_FAILURE;
3333
}
3434

35+
// Initialize configurations with file value
36+
if (ta_config_file_init(&ta_core, argc, argv) != SC_OK) {
37+
return EXIT_FAILURE;
38+
}
39+
3540
// Initialize configurations with CLI value
3641
if (ta_config_cli_init(&ta_core, argc, argv) != SC_OK) {
3742
return EXIT_FAILURE;

accelerator/message.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef enum ta_cli_arg_value_e {
3737
MWM_CLI,
3838
SEED_CLI,
3939
CACHE,
40+
CONF_CLI,
4041

4142
/** LOGGER */
4243
VERBOSE,
@@ -62,6 +63,7 @@ static struct ta_cli_argument_s {
6263
{"mwm", MWM_CLI, "minimum weight magnitude", OPTIONAL_ARG},
6364
{"seed", SEED_CLI, "IOTA seed", OPTIONAL_ARG},
6465
{"cache", CACHE, "Enable cache server with Y", REQUIRED_ARG},
66+
{"config", CONF_CLI, "Read configuration file", REQUIRED_ARG},
6567
{"verbose", VERBOSE, "Enable logger", NO_ARG}};
6668

6769
static const int cli_cmd_num = sizeof(ta_cli_arguments_g) / sizeof(struct ta_cli_argument_s);

accelerator/server.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ int main(int argc, char* argv[]) {
8080
return EXIT_FAILURE;
8181
}
8282

83+
// Initialize configurations with file value
84+
if (ta_config_file_init(&ta_core, argc, argv) != SC_OK) {
85+
return EXIT_FAILURE;
86+
}
87+
8388
// Initialize configurations with CLI value
8489
if (ta_config_cli_init(&ta_core, argc, argv) != SC_OK) {
8590
return EXIT_FAILURE;

0 commit comments

Comments
 (0)