odissey: add scheme validation routine

This commit is contained in:
Dmitry Simonenko 2016-11-07 17:19:12 +03:00
parent 59a737b9f9
commit 56392ecdca
6 changed files with 169 additions and 55 deletions

View File

@ -23,12 +23,7 @@ odissey {
workers 8
}
server default {
host "localhost"
port 4322
}
server "misc" {
server "default" {
host "localhost"
port 4321
# tls_sslmode disable
@ -41,7 +36,9 @@ odissey {
routing {
mode "forward" # round-robin
"bardb" {
"*" {
route "default"
pool_min 0
pool_max 100
client_max 100

View File

@ -6,7 +6,6 @@ CFLAGS = -I. -Wall -O0 -g -pedantic
LFLAGS =
OBJECTS = od_log.o od_lex.o od_scheme.o od_config.o odissey.o
TARGET = odissey
$(TARGET): clean $(OBJECTS)
$(CC) $(OBJECTS) $(LFLAGS) -o $(TARGET)
.c.o:

View File

@ -41,12 +41,12 @@ static odkeyword_t od_config_keywords[] =
od_keyword("host", OD_LHOST),
od_keyword("port", OD_LPORT),
od_keyword("workers", OD_LWORKERS),
od_keyword("client_max", OD_LWORKERS),
od_keyword("client_max", OD_LCLIENT_MAX),
/* server */
od_keyword("server", OD_LSERVER),
od_keyword("default", OD_LDEFAULT),
/* routing */
od_keyword("routing", OD_LSERVER),
od_keyword("routing", OD_LROUTING),
od_keyword("route", OD_LROUTE),
od_keyword("mode", OD_LMODE),
od_keyword("user", OD_LUSER),
od_keyword("password", OD_LPASSWORD),
@ -210,24 +210,15 @@ static int
od_configparse_server(odconfig_t *config)
{
odscheme_server_t *server =
od_scheme_addserver(config->scheme);
od_schemeserver_add(config->scheme);
if (server == NULL)
return -1;
odtoken_t *tk;
int rc;
/* name */
rc = od_lexpop(&config->lex, &tk);
if (rc == OD_LSTRING)
server->name = tk->v.string;
else
od_lexpush(&config->lex, tk);
/* default */
rc = od_lexpop(&config->lex, &tk);
if (rc == OD_LDEFAULT)
server->is_default = 1;
else
od_lexpush(&config->lex, tk);
if (od_confignext(config, OD_LSTRING, &tk) == -1)
return -1;
server->name = tk->v.string;
if (od_confignext(config, '{', NULL) == -1)
return -1;
int eof = 0;
@ -265,7 +256,7 @@ static int
od_configparse_route(odconfig_t *config, odtoken_t *name)
{
odscheme_route_t *route =
od_scheme_addroute(config->scheme);
od_schemeroute_add(config->scheme);
if (route == NULL)
return -1;
route->database = name->v.string;
@ -278,6 +269,12 @@ od_configparse_route(odconfig_t *config, odtoken_t *name)
{
rc = od_lexpop(&config->lex, &tk);
switch (rc) {
/* route */
case OD_LROUTE:
if (od_confignext(config, OD_LSTRING, &tk) == -1)
return -1;
route->route = tk->v.string;
continue;
/* client_max */
case OD_LCLIENT_MAX:
if (od_confignext(config, OD_LNUMBER, &tk) == -1)

View File

@ -22,8 +22,8 @@ enum {
OD_LWORKERS,
OD_LCLIENT_MAX,
OD_LSERVER,
OD_LDEFAULT,
OD_LROUTING,
OD_LROUTE,
OD_LMODE,
OD_LUSER,
OD_LPASSWORD,

View File

@ -19,11 +19,15 @@ void od_schemeinit(odscheme_t *scheme)
scheme->daemonize = 0;
scheme->log_file = NULL;
scheme->pid_file = NULL;
scheme->host = "127.0.0.1";
scheme->host = NULL;
scheme->port = 6432;
scheme->workers = 1;
scheme->client_max = 100;
scheme->routing = "forward";
scheme->pooling = NULL;
scheme->pooling_mode = OD_PUNDEF;
scheme->routing = NULL;
scheme->routing_mode = OD_RUNDEF;
scheme->server_id = 0;
od_listinit(&scheme->servers);
od_listinit(&scheme->routing_table);
}
@ -44,20 +48,34 @@ void od_schemefree(odscheme_t *scheme)
}
odscheme_server_t*
od_scheme_addserver(odscheme_t *scheme)
od_schemeserver_add(odscheme_t *scheme)
{
odscheme_server_t *s =
(odscheme_server_t*)malloc(sizeof(*s));
if (s == NULL)
return NULL;
memset(s, 0, sizeof(*s));
s->id = scheme->server_id++;
od_listinit(&s->link);
od_listappend(&scheme->servers, &s->link);
return s;
}
odscheme_server_t*
od_schemeserver_match(odscheme_t *scheme, char *name)
{
odlist_t *i;
od_listforeach(&scheme->servers, i) {
odscheme_server_t *server;
server = od_container_of(i, odscheme_server_t, link);
if (strcmp(server->name, name) == 0)
return server;
}
return NULL;
}
odscheme_route_t*
od_scheme_addroute(odscheme_t *scheme)
od_schemeroute_add(odscheme_t *scheme)
{
odscheme_route_t *r =
(odscheme_route_t*)malloc(sizeof(*r));
@ -69,6 +87,83 @@ od_scheme_addroute(odscheme_t *scheme)
return r;
}
int od_schemevalidate(odscheme_t *scheme, odlog_t *log)
{
/* pooling mode */
if (scheme->pooling == NULL) {
od_log(log, "pooling mode is not set");
return -1;
}
if (strcmp(scheme->pooling, "session") == 0)
scheme->pooling_mode = OD_PSESSION;
else
if (strcmp(scheme->pooling, "statement") == 0)
scheme->pooling_mode = OD_PSTATEMENT;
else
if (strcmp(scheme->pooling, "transaction") == 0)
scheme->pooling_mode = OD_PTRANSACTION;
if (scheme->pooling_mode == OD_PUNDEF) {
od_log(log, "unknown pooling mode");
return -1;
}
/* routing mode */
if (scheme->routing == NULL) {
od_log(log, "routing mode is not set");
return -1;
}
if (strcmp(scheme->routing, "forward") == 0)
scheme->routing_mode = OD_RFORWARD;
else
if (strcmp(scheme->routing, "round-robin") == 0)
scheme->routing_mode = OD_RROUND_ROBIN;
if (scheme->routing_mode == OD_RUNDEF) {
od_log(log, "unknown routing mode");
return -1;
}
/* listen */
if (scheme->host == NULL)
scheme->host = "127.0.0.1";
/* servers */
if (od_listempty(&scheme->servers)) {
od_log(log, "no servers are defined");
return -1;
}
odlist_t *i;
od_listforeach(&scheme->servers, i) {
odscheme_server_t *server;
server = od_container_of(i, odscheme_server_t, link);
if (server->host == NULL) {
od_log(log, "server '%s': no host is specified",
server->name);
return -1;
}
}
/* routing table */
od_listforeach(&scheme->routing_table, i) {
odscheme_route_t *route;
route = od_container_of(i, odscheme_route_t, link);
if (route->route == NULL) {
od_log(log, "route '%s': no route server is specified",
route->database);
return -1;
}
route->server = od_schemeserver_match(scheme, route->route);
if (route->server == NULL) {
od_log(log, "route '%s': no route server '%s' found",
route->route);
return -1;
}
}
return 0;
}
void od_schemeprint(odscheme_t *scheme, odlog_t *log)
{
if (scheme->config_file)
@ -103,6 +198,7 @@ void od_schemeprint(odscheme_t *scheme, odlog_t *log)
odscheme_route_t *route;
route = od_container_of(i, odscheme_route_t, link);
od_log(log, " >> %s", route->database);
od_log(log, " route '%s'", route->route);
if (route->user)
od_log(log, " user '%s'", route->user);
if (route->password)

View File

@ -10,7 +10,21 @@ typedef struct odscheme_server_t odscheme_server_t;
typedef struct odscheme_route_t odscheme_route_t;
typedef struct odscheme_t odscheme_t;
typedef enum {
OD_PUNDEF,
OD_PSESSION,
OD_PSTATEMENT,
OD_PTRANSACTION
} odpooling_t;
typedef enum {
OD_RUNDEF,
OD_RFORWARD,
OD_RROUND_ROBIN,
} odrouting_t;
struct odscheme_server_t {
int id;
char *name;
char *host;
int port;
@ -19,42 +33,53 @@ struct odscheme_server_t {
};
struct odscheme_route_t {
char *database;
char *user;
char *password;
int client_max;
int pool_min;
int pool_max;
odlist_t link;
odscheme_server_t *server;
char *route;
char *database;
char *user;
char *password;
int client_max;
int pool_min;
int pool_max;
odlist_t link;
};
struct odscheme_t {
char *config_file;
char *config_file;
/* main */
int daemonize;
char *log_file;
char *pid_file;
char *pooling;
int daemonize;
char *log_file;
char *pid_file;
char *pooling;
odpooling_t pooling_mode;
/* listen */
char *host;
int port;
int workers;
int client_max;
char *host;
int port;
int workers;
int client_max;
/* servers */
odlist_t servers;
odlist_t servers;
/* routing */
char *routing;
odlist_t routing_table;
char *routing;
odrouting_t routing_mode;
odlist_t routing_table;
odscheme_server_t *routing_default;
/* misc */
int server_id;
};
void od_schemeinit(odscheme_t*);
void od_schemefree(odscheme_t*);
odscheme_server_t*
od_scheme_addserver(odscheme_t*);
odscheme_route_t*
od_scheme_addroute(odscheme_t*);
int od_schemevalidate(odscheme_t*, odlog_t*);
void od_schemeprint(odscheme_t*, odlog_t*);
odscheme_server_t*
od_schemeserver_add(odscheme_t*);
odscheme_server_t*
od_schemeserver_match(odscheme_t*, char*);
odscheme_route_t*
od_schemeroute_add(odscheme_t*);
#endif