diff --git a/src/entry/Maat_api.cpp b/src/entry/Maat_api.cpp index 73e4b8c..b353063 100644 --- a/src/entry/Maat_api.cpp +++ b/src/entry/Maat_api.cpp @@ -499,7 +499,8 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* } int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const void* value,int size) { - _Maat_feather_t* _feather=(_Maat_feather_t*)feather; + _Maat_feather_t* _feather=(_Maat_feather_t*)feather; + struct stat attrib; int intval=0,ret=-1; switch(type) { @@ -557,36 +558,45 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo } _feather->scan_interval_ms=intval; break; - case MAAT_OPT_FULL_CFG_DIR: - if(size>(int)sizeof(_feather->full_dir)) + case MAAT_OPT_FULL_CFG_DIR: + assert(_feather->input_mode==SOURCE_NONE); + if(size>(int)sizeof(_feather->iris_ctx.full_dir)) { return -1; } - memcpy(_feather->full_dir,(const char*)value,size); + memcpy(_feather->iris_ctx.full_dir,(const char*)value,size); + _feather->input_mode=SOURCE_IRIS_FILE; break; case MAAT_OPT_INC_CFG_DIR: - if(size>(int)sizeof(_feather->inc_dir)) + if(size>(int)sizeof(_feather->iris_ctx.inc_dir)) { return -1; } - memcpy(_feather->inc_dir,(const char*)value,size); + memcpy(_feather->iris_ctx.inc_dir,(const char*)value,size); break; case MAAT_OPT_JSON_FILE_PATH: + assert(_feather->input_mode==SOURCE_NONE); ret=json2iris((const char*)value ,_feather->compile_tn,_feather->group_tn ,NULL - ,_feather->full_dir - ,sizeof(_feather->full_dir) + ,_feather->json_ctx.iris_file + ,sizeof(_feather->json_ctx.iris_file) ,_feather->logger); if(ret<0) { return -1; } - memcpy(_feather->inc_dir,_feather->full_dir,sizeof(_feather->inc_dir)); + memcpy(_feather->json_ctx.json_file, value, size); + stat(_feather->json_ctx.json_file, &attrib); + _feather->json_ctx.last_md5_time=attrib.st_ctime; + + md5_file(_feather->json_ctx.json_file, _feather->json_ctx.effective_json_md5); MESA_handle_runtime_log(_feather->logger,RLOG_LV_INFO,maat_module , - "Maat initial with JSON file %s,generate index file %s OK." - ,(const char*)value - ,_feather->full_dir); + "Maat initial with JSON file %s md5: %s,generate index file %s OK.", + _feather->json_ctx.json_file, + _feather->json_ctx.effective_json_md5, + _feather->json_ctx.iris_file); + _feather->input_mode=SOURCE_JSON_FILE; break; case MAAT_OPT_STAT_ON: _feather->stat_on=1; @@ -623,11 +633,13 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo memcpy(_feather->decrypt_key,value,size); break; case MAAT_OPT_REDIS_IP: + assert(_feather->input_mode==SOURCE_NONE); if((size_t)size>sizeof(_feather->mr_ctx.redis_ip)) { return -1; } memcpy(_feather->mr_ctx.redis_ip,value,size); + _feather->input_mode=SOURCE_REDIS; break; case MAAT_OPT_REDIS_PORT: if((size_t)size==sizeof(unsigned short)) @@ -696,61 +708,70 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo } void maat_read_full_config(_Maat_feather_t* _feather) { - struct maat_redis_ctx* mr_ctx=&(_feather->mr_ctx); - if(strlen(mr_ctx->redis_ip)>0&&mr_ctx->redis_port!=0) + struct source_redis_ctx* mr_ctx=NULL; + switch(_feather->input_mode) { - _feather->REDIS_MODE_ON=1; - MESA_handle_runtime_log(_feather->logger,RLOG_LV_INFO,maat_module , - "Maat initiate from Redis %s:%hu db%d." - ,mr_ctx->redis_ip - ,mr_ctx->redis_port - ,mr_ctx->redis_db); - mr_ctx->read_ctx=connect_redis(mr_ctx->redis_ip, mr_ctx->redis_port, mr_ctx->redis_db, _feather->logger); - if(mr_ctx->read_ctx != NULL) - { - redis_monitor_traverse(_feather->maat_version - ,mr_ctx - ,maat_start_cb - ,maat_update_cb - ,maat_finish_cb - , _feather - ,_feather->decrypt_key //Not used. - ,_feather); - } - } - else - { - if(strlen(_feather->full_dir)==0) - { - MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , - "At initiation: NO FULL_CFG_DIR or JSON_FILE_PATH. "); - - return; - } - config_monitor_traverse(_feather->maat_version, - _feather->full_dir, - maat_start_cb, - maat_update_cb, - maat_finish_cb, - _feather, - _feather->decrypt_key, - _feather->logger); - } - if(_feather->update_tmp_scanner==NULL) - { - if(_feather->REDIS_MODE_ON==1) - { - MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , - "At initiation: no avilable rule in redis in %s:%hu" - ,mr_ctx->redis_ip - ,mr_ctx->redis_port); - - } - else - { - MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , - "At initiation: no valid index file in %s",_feather->full_dir); - } + case SOURCE_REDIS: + mr_ctx=&(_feather->mr_ctx); + MESA_handle_runtime_log(_feather->logger,RLOG_LV_INFO,maat_module , + "Maat initiate from Redis %s:%hu db%d." + ,mr_ctx->redis_ip + ,mr_ctx->redis_port + ,mr_ctx->redis_db); + mr_ctx->read_ctx=connect_redis(mr_ctx->redis_ip, mr_ctx->redis_port, mr_ctx->redis_db, _feather->logger); + if(mr_ctx->read_ctx != NULL) + { + redis_monitor_traverse(_feather->maat_version + ,mr_ctx + ,maat_start_cb + ,maat_update_cb + ,maat_finish_cb + , _feather + ,_feather->decrypt_key //Not used. + ,_feather); + } + if(_feather->update_tmp_scanner) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: no avilable rule in redis in %s:%hu" + ,mr_ctx->redis_ip + ,mr_ctx->redis_port); + } + break; + case SOURCE_IRIS_FILE: + config_monitor_traverse(_feather->maat_version, + _feather->iris_ctx.full_dir, + maat_start_cb, + maat_update_cb, + maat_finish_cb, + _feather, + _feather->decrypt_key, + _feather->logger); + if(!_feather->update_tmp_scanner) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: NO effective rule in %s.", + _feather->iris_ctx.full_dir); + } + break; + case SOURCE_JSON_FILE: + config_monitor_traverse(_feather->maat_version, + _feather->json_ctx.iris_file, + maat_start_cb, + maat_update_cb, + maat_finish_cb, + _feather, + _feather->decrypt_key, + _feather->logger); + if(!_feather->update_tmp_scanner) + { + MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module , + "At initiation: NO efffective rule in JSON generate %s.", + _feather->json_ctx.iris_file); + } + break; + default: + break; } _feather->scanner=_feather->update_tmp_scanner; _feather->update_tmp_scanner=NULL; diff --git a/src/entry/Maat_command.cpp b/src/entry/Maat_command.cpp index 5c3335e..bf6f8b4 100644 --- a/src/entry/Maat_command.cpp +++ b/src/entry/Maat_command.cpp @@ -92,7 +92,7 @@ redisContext * connect_redis(const char*redis_ip, int redis_port, int redis_db, } -int connect_redis_for_write(struct maat_redis_ctx* mr_ctx, void* logger) +int connect_redis_for_write(struct source_redis_ctx* mr_ctx, void* logger) { assert(mr_ctx->write_ctx==NULL); mr_ctx->write_ctx=connect_redis(mr_ctx->redis_ip, mr_ctx->redis_port, mr_ctx->redis_db, logger); @@ -1728,7 +1728,7 @@ void get_foreign_conts(redisContext *ctx, struct serial_rule_t* rule_list, int r return; } -void redis_monitor_traverse(long long version, struct maat_redis_ctx* mr_ctx, +void redis_monitor_traverse(long long version, struct source_redis_ctx* mr_ctx, void (*start)(long long,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para int (*update)(const char* ,const char*,void* ),//table name ,line ,u_para void (*finish)(void*),//u_para @@ -2287,7 +2287,7 @@ int Maat_cmd_commit(Maat_feather_t feather) redisReply* data_reply=NULL; struct serial_rule_t* s_rule=NULL; - if(_feather->REDIS_MODE_ON==0) + if(_feather->input_mode!=SOURCE_REDIS) { return -1; } diff --git a/src/entry/Maat_rule.cpp b/src/entry/Maat_rule.cpp index fc19f51..26e1171 100644 --- a/src/entry/Maat_rule.cpp +++ b/src/entry/Maat_rule.cpp @@ -32,7 +32,7 @@ #include "stream_fuzzy_hash.h" #include "gram_index_engine.h" -int MAAT_FRAME_VERSION_2_4_20181129=1; +int MAAT_FRAME_VERSION_2_4_20181202=1; const char* CHARSET_STRING[]={"NONE","gbk","big5","unicode","utf8","bin", "unicode_ascii_esc","unicode_ascii_aligned","unicode_ncr_dec","unicode_ncr_hex","url_encode_gb2312","url_encode_utf8",""}; @@ -3439,11 +3439,14 @@ int maat_update_cb(const char* table_name,const char* line,void *u_para) void *thread_rule_monitor(void *arg) { struct _Maat_feather_t *feather=(struct _Maat_feather_t *)arg; - const char* inc_cfg_dir=(const char*)feather->inc_dir; struct _Maat_scanner_t* old_scanner=NULL; long expr_wait_q_cnt=0; int scan_dir_cnt=0; - UNUSED int ret=0; + int ret=0; + char md5_tmp[MD5_DIGEST_LENGTH*2+1]={0}; + char tmp_dir[MAX_TABLE_NAME_LEN]={0}; + struct stat attrib; + char maat_name[16];//Defined by prctl: The name can be up to 16 bytes long,and should // be null terminated if it contains fewer bytes. if(strlen(feather->instance_name)>0) @@ -3470,29 +3473,78 @@ void *thread_rule_monitor(void *arg) scan_dir_cnt++; if(0==pthread_mutex_trylock(&(feather->backgroud_update_mutex))) { - if(feather->REDIS_MODE_ON==1) + switch(feather->input_mode) { - redis_monitor_traverse(feather->maat_version - ,&(feather->mr_ctx) - ,maat_start_cb - ,maat_update_cb - ,maat_finish_cb - ,feather - ,feather->decrypt_key //Not used. - ,feather); + case SOURCE_REDIS: + redis_monitor_traverse(feather->maat_version, + &(feather->mr_ctx), + maat_start_cb, + maat_update_cb, + maat_finish_cb, + feather, + feather->decrypt_key, //Not used. + feather); + break; + case SOURCE_IRIS_FILE: + config_monitor_traverse(feather->maat_version, + feather->iris_ctx.inc_dir, + maat_start_cb, + maat_update_cb, + maat_finish_cb, + feather, + feather->decrypt_key, + feather->logger); + break; + case SOURCE_JSON_FILE: + memset(md5_tmp, 0, sizeof(md5_tmp)); + memset(tmp_dir, 0, sizeof(tmp_dir)); + stat(feather->json_ctx.json_file, &attrib); + if(attrib.st_ctime!=feather->json_ctx.last_md5_time) + { + feather->json_ctx.last_md5_time=attrib.st_ctime; + md5_file(feather->json_ctx.json_file, md5_tmp); + if(0!=strcmp(md5_tmp,feather->json_ctx.effective_json_md5)) + { + ret=json2iris(feather->json_ctx.json_file, + feather->compile_tn, feather->group_tn, + NULL, + tmp_dir, + sizeof(tmp_dir), + feather->logger); + if(ret<0) + { + MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module , + "Maat re-initiate with JSON file %s failed, md5: %s", + feather->json_ctx.json_file, + md5_tmp); + } + else + { + strcpy(feather->json_ctx.effective_json_md5, md5_tmp); + strcpy(feather->json_ctx.iris_file, tmp_dir); + config_monitor_traverse(0, + feather->json_ctx.iris_file, + maat_start_cb, + maat_update_cb, + maat_finish_cb, + feather, + feather->decrypt_key, + feather->logger); + MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module , + "Maat re-initiate with JSON file %s success, md5: %s", + feather->json_ctx.json_file, + md5_tmp); + + } + + } + } + break; + default: + assert(0); + break; } - else - { - config_monitor_traverse(feather->maat_version, - inc_cfg_dir, - maat_start_cb, - maat_update_cb, - maat_finish_cb, - feather, - feather->decrypt_key, - feather->logger); - } - + if(feather->update_tmp_scanner!=NULL) { old_scanner=feather->scanner; @@ -3567,7 +3619,7 @@ void *thread_rule_monitor(void *arg) alignment_int64_array_free(feather->hit_cnt); alignment_int64_array_free(feather->orphan_group_saving); alignment_int64_array_free(feather->last_region_saving); - if(feather->REDIS_MODE_ON==1) + if(feather->input_mode==SOURCE_REDIS) { if(feather->mr_ctx.read_ctx) { diff --git a/src/entry/Maat_utils.cpp b/src/entry/Maat_utils.cpp index c2b5732..1ceffab 100644 --- a/src/entry/Maat_utils.cpp +++ b/src/entry/Maat_utils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "Maat_utils.h" pid_t gettid() @@ -177,10 +178,43 @@ int system_cmd_mv(const char* src_file,const char*dst_file) snprintf(cmd,sizeof(cmd), "mv %s %s", src_file, dst_file); return system(cmd); } +int system_cmd_cp(const char* src_file,const char*dst_file) +{ + char cmd[MAX_SYSTEM_CMD_LEN] = { 0 }; + snprintf(cmd,sizeof(cmd), "cp -f %s %s", src_file, dst_file); + return system(cmd); +} + int system_cmd_rm(const char* src_file) { char cmd[MAX_SYSTEM_CMD_LEN] = { 0 }; snprintf(cmd,sizeof(cmd), "rm %s -f", src_file); return system(cmd); } +char* md5_file(const char* filename, char* md5string) +{ + FILE* fp=NULL; + int i=0; + unsigned char md5[MD5_DIGEST_LENGTH]; + struct stat file_info; + stat(filename, &file_info); + size_t file_size=file_info.st_size; + + fp=fopen(filename,"r"); + if(fp==NULL) + { + return NULL; + } + char* file_buff=(char*)malloc(file_size); + fread(file_buff,1,file_size,fp); + fclose(fp); + + MD5((const unsigned char *)(file_buff), (unsigned long)(file_size), md5); + for(i = 0; i < MD5_DIGEST_LENGTH; ++i) + { + sprintf(&md5string[i*2], "%02x", (unsigned int)md5[i]); + } + free(file_buff); + return md5string; +} diff --git a/src/inc_internal/Maat_rule_internal.h b/src/inc_internal/Maat_rule_internal.h index a20affc..475eb7d 100644 --- a/src/inc_internal/Maat_rule_internal.h +++ b/src/inc_internal/Maat_rule_internal.h @@ -17,6 +17,7 @@ #include "alignment_int64.h" #include #include +#include extern const char *maat_module; @@ -359,16 +360,6 @@ struct rule_tag char* tag_name; char* tag_val; }; -struct maat_redis_ctx -{ - redisContext *read_ctx; - redisContext *write_ctx; - char redis_ip[64]; - int redis_port; - int redis_db; - time_t last_reconnect_time; -}; - struct _Maat_scanner_t { long long version; @@ -394,6 +385,34 @@ struct _Maat_scanner_t int max_thread_num; iconv_t iconv_handle[MAX_CHARSET_NUM][MAX_CHARSET_NUM];//iconv_handle[to][from] }; +enum data_source +{ + SOURCE_NONE=0, + SOURCE_REDIS, + SOURCE_IRIS_FILE, + SOURCE_JSON_FILE +}; +struct source_iris_ctx +{ + char inc_dir[MAX_TABLE_NAME_LEN]; + char full_dir[MAX_TABLE_NAME_LEN]; +}; +struct source_json_ctx +{ + char json_file[MAX_TABLE_NAME_LEN]; + char iris_file[MAX_TABLE_NAME_LEN]; + char effective_json_md5[MD5_DIGEST_LENGTH*2+1]; + time_t last_md5_time; +}; +struct source_redis_ctx +{ + redisContext *read_ctx; + redisContext *write_ctx; + char redis_ip[64]; + int redis_port; + int redis_db; + time_t last_reconnect_time; +}; struct _Maat_feather_t { struct _Maat_scanner_t *scanner; @@ -403,6 +422,13 @@ struct _Maat_feather_t int DEFERRED_LOAD_ON; int GROUP_MODE_ON; int REDIS_MODE_ON; + enum data_source input_mode; + union + { + struct source_iris_ctx iris_ctx; + struct source_json_ctx json_ctx; + struct source_redis_ctx mr_ctx; + }; int still_working; int scan_interval_ms; int effect_interval_ms; @@ -416,8 +442,7 @@ struct _Maat_feather_t long long last_full_version; int scan_thread_num; int rule_scan_type; - char inc_dir[MAX_TABLE_NAME_LEN]; - char full_dir[MAX_TABLE_NAME_LEN]; + char stat_file[MAX_TABLE_NAME_LEN]; char instance_name[MAX_TABLE_NAME_LEN]; char table_info_fn[MAX_TABLE_NAME_LEN]; @@ -426,8 +451,7 @@ struct _Maat_feather_t pthread_mutex_t backgroud_update_mutex; unsigned char decrypt_key[MAX_TABLE_NAME_LEN]; pthread_t cfg_mon_t; - struct maat_redis_ctx mr_ctx; - + int AUTO_NUMBERING_ON; // redisContext *redis_write_ctx; // not thread safe. @@ -542,8 +566,9 @@ void empty_serial_rules(struct serial_rule_t* rule); int exec_serial_rule(redisContext* ctx,struct serial_rule_t* s_rule,int serial_rule_num, long long server_time, void* logger); long long redis_server_time(redisContext* ctx); redisContext * connect_redis(const char*redis_ip, int redis_port, int redis_db, void* logger); +char* md5_file(const char* filename, char* md5string); -void redis_monitor_traverse(long long version, struct maat_redis_ctx* mr_ctx, +void redis_monitor_traverse(long long version, struct source_redis_ctx* mr_ctx, void (*start)(long long,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para int (*update)(const char* ,const char*,void* ),//table name ,line ,u_para void (*finish)(void*),//u_para diff --git a/src/inc_internal/Maat_utils.h b/src/inc_internal/Maat_utils.h index 6d23a3b..2843db1 100644 --- a/src/inc_internal/Maat_utils.h +++ b/src/inc_internal/Maat_utils.h @@ -44,4 +44,7 @@ char* str_unescape(char* s); pid_t gettid(void); int system_cmd_mkdir(const char* path); int system_cmd_rm(const char* src_file); +int system_cmd_mv(const char* src_file,const char*dst_file); +int system_cmd_cp(const char* src_file,const char*dst_file); +char* md5_file(const char* filename, char* md5string); diff --git a/src/version.map b/src/version.map index 08a00da..7f11e6b 100644 --- a/src/version.map +++ b/src/version.map @@ -6,6 +6,8 @@ global: *GIE_*; #for test *my_scandir*; + *md5_file*; + *system_cmd_*; }; local: *; }; \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e56f5ae..ef8db6a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,4 +13,5 @@ file(COPY rule DESTINATION ./) file(COPY testdata DESTINATION ./) file(COPY testdata_uni2ascii DESTINATION ./) file(COPY test_streamfiles DESTINATION ./) -file(COPY ntcrule DESTINATION ./) \ No newline at end of file +file(COPY ntcrule DESTINATION ./) +file(COPY json_update DESTINATION ./) \ No newline at end of file diff --git a/test/json_update/corrupted.json b/test/json_update/corrupted.json new file mode 100644 index 0000000..66db4d1 --- /dev/null +++ b/test/json_update/corrupted.json @@ -0,0 +1,32 @@ +{ + "compile_table": "COMPILE", + "group_table": "GROUP", + "rules": [ + { + "compile_id": 1 + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "anything", + "is_valid": "yes", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "hello&world", + "expr_type": "none", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + } + ] +} diff --git a/test/json_update/new.json b/test/json_update/new.json new file mode 100644 index 0000000..5e3a1a7 --- /dev/null +++ b/test/json_update/new.json @@ -0,0 +1,31 @@ +{ + "compile_table": "COMPILE", + "group_table": "GROUP", + "rules": [ + { + "compile_id": 2, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "anything", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "MESA&Maat", + "expr_type": "and", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + } + ] +} diff --git a/test/json_update/old.json b/test/json_update/old.json new file mode 100644 index 0000000..3c5b7c8 --- /dev/null +++ b/test/json_update/old.json @@ -0,0 +1,32 @@ +{ + "compile_table": "COMPILE", + "group_table": "GROUP", + "rules": [ + { + "compile_id": 1, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "anything", + "is_valid": "yes", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_URL", + "table_type": "string", + "table_content": { + "keywords": "hello&world", + "expr_type": "and", + "match_method": "sub", + "format": "uncase plain" + } + } + ] + } + ] + } + ] +} diff --git a/test/test_maatframe.cpp b/test/test_maatframe.cpp index e2d36f5..9930379 100644 --- a/test/test_maatframe.cpp +++ b/test/test_maatframe.cpp @@ -30,8 +30,8 @@ const char* inc_cfg_dir="./rule/inc/index/"; extern int my_scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *)); - - +extern char* md5_file(const char* filename, char* md5string); +extern int system_cmd_cp(const char* src_file,const char*dst_file); Maat_feather_t g_feather=NULL; void *g_logger=NULL; int g_iThreadNum=4; @@ -39,6 +39,97 @@ const char* table_info_path="./table_info.conf"; int scan_interval_ms=1; int effective_interval_ms=0; +void scan_with_old_or_new_cfg(Maat_feather_t feather, int hit_old) +{ + const char* hit_old_data="Hello world! I'm eve."; + const char* hit_new_data="Maat was borned in MESA."; + + const char* table_name="HTTP_URL"; + + scan_status_t mid=NULL; + int table_id=0, ret=0; + + struct Maat_rule_t result; + + table_id=Maat_table_register(feather,table_name); + ASSERT_GT(table_id, 0); + memset(&result, 0, sizeof(result)); + ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, hit_old_data, strlen(hit_old_data), + &result,NULL, 1, + &mid, 0); + if(hit_old) + { + EXPECT_EQ(ret, 1); + EXPECT_TRUE(result.config_id==1); + } + else + { + EXPECT_EQ(ret, 0); + } + Maat_clean_status(&mid); + + memset(&result, 0, sizeof(result)); + ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, hit_new_data, strlen(hit_new_data), + &result,NULL, 1, + &mid, 0); + if(!hit_old) + { + EXPECT_EQ(ret, 1); + EXPECT_TRUE(result.config_id==2); + } + else + { + EXPECT_EQ(ret, 0); + } + + Maat_clean_status(&mid); + +} + +const char* watched_json="./json_update/maat.json"; +const char* old_json="./json_update/old.json"; +const char* new_json="./json_update/new.json"; +const char* corrupted_json="./json_update/corrupted.json"; + +class MaatJSONTest : public testing::Test +{ + +protected: + static void SetUpTestCase() + { + system_cmd_cp(old_json, watched_json); + _shared_feather_j=Maat_feather(g_iThreadNum, table_info_path, g_logger); + Maat_set_feather_opt(_shared_feather_j, MAAT_OPT_JSON_FILE_PATH, watched_json, strlen(watched_json)+1); + Maat_set_feather_opt(_shared_feather_j, MAAT_OPT_SCANDIR_INTERVAL_MS,&scan_interval_ms, sizeof(scan_interval_ms)); + + Maat_initiate_feather(_shared_feather_j); + + } + static void TearDownTestCase() + { + Maat_burn_feather(_shared_feather_j); + } + // Some expensive resource shared by all tests. + static Maat_feather_t _shared_feather_j; + static void *logger; +}; +Maat_feather_t MaatJSONTest::_shared_feather_j; + + +TEST_F(MaatJSONTest, OldCfg) +{ + scan_with_old_or_new_cfg(MaatJSONTest::_shared_feather_j, 1); +} +TEST_F(MaatJSONTest, NewCfg) +{ + system_cmd_cp(corrupted_json, watched_json); + sleep(2); + scan_with_old_or_new_cfg(MaatJSONTest::_shared_feather_j, 1); + system_cmd_cp(new_json, watched_json); + sleep(2); + scan_with_old_or_new_cfg(MaatJSONTest::_shared_feather_j, 0); +} + void Maat_read_entry_start_cb(int update_type,void* u_para) { return; @@ -1212,32 +1303,7 @@ void prepare_file_to_set(const char* filename, char** file_buff, size_t* file_si snprintf(file_key, key_size, "__FILE_%s", md5string); return; } -char* md5_file(const char* filename, char* md5string) -{ - FILE* fp=NULL; - int i=0; - unsigned char md5[MD5_DIGEST_LENGTH]; - struct stat file_info; - stat(filename, &file_info); - size_t file_size=file_info.st_size; - fp=fopen(filename,"r"); - if(fp==NULL) - { - return NULL; - } - char* file_buff=(char*)malloc(file_size); - fread(file_buff,1,file_size,fp); - fclose(fp); - - MD5((const unsigned char *)(file_buff), (unsigned long)(file_size), md5); - for(i = 0; i < MD5_DIGEST_LENGTH; ++i) - { - sprintf(&md5string[i*2], "%02x", (unsigned int)md5[i]); - } - free(file_buff); - return md5string; -} int is_same_file(const char* filename1, const char* filename2) { char md5string[2][MD5_DIGEST_LENGTH*2+1];