From c547d7ce5b90ec6ca2479878b17958698772aeb3 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 20 Jul 2017 23:07:37 +0900 Subject: [PATCH] add mongo DB client --- INSTALL.md | 2 +- configure.ac | 6 +- lib/base/Makefile.am | 3 +- lib/base/context.c | 168 +++++++++++++++++++++++++++++-------------- lib/base/context.h | 13 +++- src/init.c | 6 ++ 6 files changed, 139 insertions(+), 59 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 154531031d..e638bfb7d4 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,7 +2,7 @@ Prerequisite ============ sudo apt-get install git cscope gdb - sudo apt-get install autoconf libtool m4 + sudo apt-get install autoconf libtool m4 pkg-config sudo apt-get install libsctp-dev sudo apt-get install freediameter-dev sudo apt-get install libmongoc-1.0-0 diff --git a/configure.ac b/configure.ac index c43d849f24..09deeebf6e 100644 --- a/configure.ac +++ b/configure.ac @@ -60,8 +60,7 @@ AH_VERBATIM([_REENTRANT], #endif ]) -dnl Checks for programs. -# We need a C compiler. +dnl Checks CC and freinds AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL @@ -291,6 +290,9 @@ AC_CHECK_LIB([fdcore], [fd_core_initialize], [LIBS="${LIBS} -lfdcore"]) AC_CHECK_LIB([fdproto], [fd_libproto_init], [LIBS="${LIBS} -lfdproto"]) AC_CHECK_LIB([gnutls], [gnutls_global_init], [LIBS="${LIBS} -lgnutls"]) +PKG_CHECK_MODULES([MONGOC], libmongoc-1.0 >= 1.6.3) +LIBS="$LIBS $MONGOC_LIBS" + ##################### #### Conclusion. #### ##################### diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index f89fe0df8e..a82dfac835 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -9,7 +9,8 @@ nodist_libbase_la_SOURCES = \ types.c context.c AM_CPPFLAGS = \ - -I$(top_srcdir)/lib/core/include + -I$(top_srcdir)/lib/core/include \ + @MONGOC_CFLAGS@ AM_CFLAGS = \ -Wall -Werror diff --git a/lib/base/context.c b/lib/base/context.c index bb31ff367c..9f746c3568 100644 --- a/lib/base/context.c +++ b/lib/base/context.c @@ -1,5 +1,6 @@ #define TRACE_MODULE _context +#include #include "core_file.h" #include "context.h" @@ -22,6 +23,77 @@ status_t context_init() return CORE_OK; } +status_t context_final() +{ + d_assert(context_initialized == 1, return CORE_ERROR, + "Context already has been finalized"); + + context_db_final(); + + context_initialized = 0; + + return CORE_OK; +} + +context_t* context_self() +{ + return &self; +} + +status_t context_read_file(char *file_path) +{ + char buf[MAX_ERROR_STRING_LEN]; + config_t *config = &self.config; + status_t rv; + file_t *file; + + jsmn_parser parser; + size_t json_len; + int result; + + config->path = file_path; + if (config->path == NULL) config->path = DEFAULT_CONFIG_FILE_PATH; + + rv = file_open(&file, config->path, FILE_READ, FILE_OS_DEFAULT); + if (rv != CORE_OK) + { + d_fatal("Can't open configuration file '%s' (errno = %d, %s)", + config->path, rv, core_strerror(rv, buf, MAX_ERROR_STRING_LEN)); + return rv; + } + + json_len = MAX_CONFIG_FILE_SIZE; + rv = file_read(file, config->json, &json_len); + if (rv != CORE_OK) + { + d_fatal("Can't read configuration file '%s' (errno = %d, %s)", + config->path, rv, core_strerror(rv, buf, MAX_ERROR_STRING_LEN)); + return rv; + } + file_close(file); + + jsmn_init(&parser); + result = jsmn_parse(&parser, config->json, strlen(config->json), + config->token, sizeof(config->token)/sizeof(config->token[0])); + if (result < 0) + { + d_fatal("Failed to parse configuration file '%s' (jsmnerr = %d)", + config->path, result); + return CORE_ERROR; + } + + if (result < 1 || config->token[0].type != JSMN_OBJECT) + { + d_fatal("Failed to parse configuration file '%s' (OBJECT expected)", + config->path); + return CORE_ERROR; + } + + d_print(" Config '%s'\n", config->path); + + return CORE_OK; +} + status_t context_parse_config() { config_t *config = &self.config; @@ -92,72 +164,64 @@ status_t context_parse_config() return CORE_OK; } -status_t context_final() +status_t context_db_init(char *db_uri) { - d_assert(context_initialized == 1, return CORE_ERROR, - "HyperCell context already has been finalized"); + bson_t reply; + bson_error_t error; + bson_iter_t iter; - context_initialized = 0; + const mongoc_uri_t *uri; - return CORE_OK; -} + mongoc_init(); -context_t* context_self() -{ - return &self; -} - -status_t context_read_file(char *file_path) -{ - char buf[MAX_ERROR_STRING_LEN]; - config_t *config = &self.config; - status_t rv; - file_t *file; - - jsmn_parser parser; - size_t json_len; - int result; - - config->path = file_path; - if (config->path == NULL) config->path = DEFAULT_CONFIG_FILE_PATH; - - rv = file_open(&file, config->path, FILE_READ, FILE_OS_DEFAULT); - if (rv != CORE_OK) + self.db_client = mongoc_client_new(db_uri); + if (!self.db_client) { - d_fatal("Can't open configuration file '%s' (errno = %d, %s)", - config->path, rv, core_strerror(rv, buf, MAX_ERROR_STRING_LEN)); - return rv; - } + d_error("Failed to parse DB URI [%s]", db_uri); - json_len = MAX_CONFIG_FILE_SIZE; - rv = file_read(file, config->json, &json_len); - if (rv != CORE_OK) - { - d_fatal("Can't read configuration file '%s' (errno = %d, %s)", - config->path, rv, core_strerror(rv, buf, MAX_ERROR_STRING_LEN)); - return rv; - } - file_close(file); - - jsmn_init(&parser); - result = jsmn_parse(&parser, config->json, strlen(config->json), - config->token, sizeof(config->token)/sizeof(config->token[0])); - if (result < 0) - { - d_fatal("Failed to parse configuration file '%s' (jsmnerr = %d)", - config->path, result); + context_db_final(); return CORE_ERROR; } - if (result < 1 || config->token[0].type != JSMN_OBJECT) + mongoc_client_set_error_api(self.db_client, 2); + + uri = mongoc_client_get_uri(self.db_client); + d_assert(uri, context_db_final(); return CORE_ERROR, + "Database is not defined in DB_URI [%s]", db_uri); + + self.db_name = (char *)mongoc_uri_get_database(uri); + d_assert(self.db_name, context_db_final(); return CORE_ERROR, + "Database is not defined in DB_URI [%s]", db_uri); + + self.database = mongoc_client_get_database(self.db_client, self.db_name); + d_assert(self.database, context_db_final(); return CORE_ERROR, + "Database is not defined in DB_URI [%s]", db_uri); + + if (!mongoc_client_get_server_status(self.db_client, NULL, &reply, &error)) { - d_fatal("Failed to parse configuration file '%s' (OBJECT expected)", - config->path); + d_error("Failed to conect to server [%s]", db_uri); + + context_db_final(); return CORE_ERROR; } - d_print(" Config '%s'\n", config->path); + d_assert(bson_iter_init_find(&iter, &reply, "ok"), + bson_destroy(&reply); context_db_final(); return CORE_ERROR, + "Invalid reply for server status [%s]", db_uri); + bson_destroy(&reply); return CORE_OK; } +status_t context_db_final() +{ + if (self.database) + mongoc_database_destroy(self.database); + + if (self.db_client) + mongoc_client_destroy(self.db_client); + + mongoc_cleanup(); + + return CORE_OK; +} diff --git a/lib/base/context.h b/lib/base/context.h index bda0731572..67c2a97713 100644 --- a/lib/base/context.h +++ b/lib/base/context.h @@ -1,5 +1,5 @@ -#ifndef __CONTEXT__ -#define __CONTEXT__ +#ifndef __CONTEXT_H__ +#define __CONTEXT_H__ #include "core_debug.h" #include "core_param.h" @@ -24,7 +24,11 @@ typedef struct _context_t { config_t config; char *log_path; + char *db_uri; + void *db_client; + char *db_name; + void *database; } context_t; CORE_DECLARE(status_t) context_init(void); @@ -34,8 +38,11 @@ CORE_DECLARE(context_t*) context_self(void); CORE_DECLARE(status_t) context_read_file(char *file_path); CORE_DECLARE(status_t) context_parse_config(void); +CORE_DECLARE(status_t) context_db_init(char *db_uri); +CORE_DECLARE(status_t) context_db_final(void); + #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* __CONTEXT__ */ +#endif /* __CONTEXT_H__ */ diff --git a/src/init.c b/src/init.c index 90e48365a5..ac2f5751a7 100644 --- a/src/init.c +++ b/src/init.c @@ -38,6 +38,12 @@ status_t app_will_initialize(char *config_path, char *log_path) d_assert(logger_pid > 0, return -1, "logger_start() failed"); } + if (context_self()->db_uri) + { + rv = context_db_init(context_self()->db_uri); + if (rv != CORE_OK) return rv; + } + return CORE_OK; }