diff --git a/include/maat.h b/include/maat.h index e3dfaa2..07ae691 100644 --- a/include/maat.h +++ b/include/maat.h @@ -187,6 +187,8 @@ int maat_helper_verify_regex_expression(const char *expression); /* maat table API */ int maat_get_table_id(struct maat *instance, const char *table_name); +const char *maat_get_table_schema_tag(struct maat *instance, int table_id); + /* return 0 if success, otherwise return -1 */ int maat_table_callback_register(struct maat *instance, int table_id, maat_start_callback_t *start, diff --git a/src/inc_internal/maat_limits.h b/src/inc_internal/maat_limits.h index c8685fb..b9119df 100644 --- a/src/inc_internal/maat_limits.h +++ b/src/inc_internal/maat_limits.h @@ -16,10 +16,11 @@ extern "C" { #endif -#define MAX_KEYWORDS_STR_LEN 1024 -#define MAX_MAAT_STAT_NUM 64 -#define MAX_NAME_STR_LEN 64 -#define MAX_IP_STR_LEN 64 +#define MAX_KEYWORDS_STR_LEN 1024 +#define MAX_TAG_STR_LEN 2048 +#define MAX_MAAT_STAT_NUM 64 +#define MAX_NAME_STR_LEN 64 +#define MAX_IP_STR_LEN 64 #define MAX_INSTANCE_NAME_LEN 15 #define MAX_GROUP_IDS_STR_LEN 256 diff --git a/src/inc_internal/maat_table.h b/src/inc_internal/maat_table.h index 6c38a70..494ba91 100644 --- a/src/inc_internal/maat_table.h +++ b/src/inc_internal/maat_table.h @@ -79,6 +79,8 @@ int table_manager_get_conj_parent_table_ids(struct table_manager *tbl_mgr, const const char *table_manager_get_table_name(struct table_manager *tbl_mgr, int table_id); +const char *table_manager_get_table_schema_tag(struct table_manager *tbl_mgr, int table_id); + enum table_type table_manager_get_table_type(struct table_manager *tbl_mgr, int table_id); int table_manager_get_default_compile_table_id(struct table_manager *tbl_mgr); diff --git a/src/maat_api.c b/src/maat_api.c index 2dad86e..4a77d36 100644 --- a/src/maat_api.c +++ b/src/maat_api.c @@ -493,6 +493,16 @@ int maat_get_table_id(struct maat *maat_inst, const char *table_name) return table_manager_get_table_id(table_mgr, table_name); } +const char *maat_get_table_schema_tag(struct maat *maat_inst, int table_id) +{ + if (NULL == maat_inst || table_id < 0) { + return NULL; + } + + struct table_manager *table_mgr = maat_inst->tbl_mgr; + return table_manager_get_table_schema_tag(table_mgr, table_id); +} + static inline void maat_runtime_ref_inc(struct maat_runtime *maat_rt, int thread_id) { if (NULL == maat_rt) { diff --git a/src/maat_table.c b/src/maat_table.c index 166b619..d216a9a 100644 --- a/src/maat_table.c +++ b/src/maat_table.c @@ -34,7 +34,9 @@ struct maat_table { int table_id; - char table_name[MAX_NAME_STR_LEN]; + char table_name[MAX_NAME_STR_LEN + 1]; + char schema_tag[MAX_TAG_STR_LEN + 1]; + size_t schema_tag_len; enum table_type table_type; int valid_column; void *schema; @@ -517,15 +519,45 @@ maat_table_new(cJSON *json, struct maat_kv_store *reserved_word_map, } ptable->table_id = item->valueint; + size_t str_len = 0; item = cJSON_GetObjectItem(json, "table_name"); // already validate in register_tbl_name2id if (item->type == cJSON_Array) { cJSON *tmp_item = cJSON_GetArrayItem(item, 0); - memcpy(ptable->table_name, tmp_item->valuestring, - strlen(tmp_item->valuestring)); + str_len = strlen(tmp_item->valuestring); + if (str_len > MAX_NAME_STR_LEN) { + log_fatal(logger, MODULE_TABLE, + "[%s:%d] table:%s name length exceed maximum:%d", + __FUNCTION__, __LINE__, tmp_item->valuestring, + MAX_NAME_STR_LEN); + goto error; + } + memcpy(ptable->table_name, tmp_item->valuestring, str_len); } else { //cJSON_String - memcpy(ptable->table_name, item->valuestring, strlen(item->valuestring)); + str_len = strlen(item->valuestring); + if (str_len > MAX_NAME_STR_LEN) { + log_fatal(logger, MODULE_TABLE, + "[%s:%d] table:%s name length exceed maximum:%d", + __FUNCTION__, __LINE__, item->valuestring, + MAX_NAME_STR_LEN); + goto error; + } + memcpy(ptable->table_name, item->valuestring, str_len); + } + + item = cJSON_GetObjectItem(json, "schema_tag"); + if (item != NULL && item->type == cJSON_String) { + str_len = strlen(item->valuestring); + if (str_len > MAX_TAG_STR_LEN) { + log_fatal(logger, MODULE_TABLE, + "[%s:%d] table:%s tag length exceed maximum:%d", + __FUNCTION__, __LINE__, item->valuestring, + MAX_TAG_STR_LEN); + goto error; + } + memcpy(ptable->schema_tag, item->valuestring, str_len); + ptable->schema_tag_len = str_len; } item = cJSON_GetObjectItem(json, "table_type"); @@ -537,7 +569,7 @@ maat_table_new(cJSON *json, struct maat_kv_store *reserved_word_map, } ret = maat_kv_read(reserved_word_map, item->valuestring, - (long long *)&(ptable->table_type), 1); + (long long *)&(ptable->table_type), 1); if (ret < 0) { log_fatal(logger, MODULE_TABLE, "[%s:%d] table:%s table_type %s is illegal", @@ -1078,6 +1110,19 @@ const char *table_manager_get_table_name(struct table_manager *tbl_mgr, int tabl return tbl_mgr->tbl[table_id]->table_name; } +const char *table_manager_get_table_schema_tag(struct table_manager *tbl_mgr, int table_id) +{ + if (NULL == tbl_mgr || table_id < 0) { + return NULL; + } + + if (NULL == tbl_mgr->tbl[table_id] || 0 == tbl_mgr->tbl[table_id]->schema_tag_len) { + return NULL; + } + + return tbl_mgr->tbl[table_id]->schema_tag; +} + enum table_type table_manager_get_table_type(struct table_manager *tbl_mgr, int table_id) { if (NULL == tbl_mgr || table_id < 0 || table_id >= MAX_TABLE_NUM) { diff --git a/src/version.map b/src/version.map index d2b1474..4028108 100644 --- a/src/version.map +++ b/src/version.map @@ -6,6 +6,7 @@ global: maat_new; maat_free; maat_get_table_id; + maat_get_table_schema_tag; maat_reload_log_level; maat_table*; maat_compile_table*; diff --git a/test/maat_framework_gtest.cpp b/test/maat_framework_gtest.cpp index 3d07fc1..853e73e 100644 --- a/test/maat_framework_gtest.cpp +++ b/test/maat_framework_gtest.cpp @@ -5964,6 +5964,158 @@ TEST_F(VirtualTable, basic) { state = NULL; } +class TableSchemaTag : public testing::Test +{ +protected: + static void SetUpTestCase() { + const char *accept_tags = "{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"}," + "{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; + char redis_ip[64] = "127.0.0.1"; + int redis_port = 6379; + int redis_db = 0; + + logger = log_handle_create("./maat_framework_gtest.log", 0); + int ret = write_config_to_redis(redis_ip, redis_port, redis_db, logger); + if (ret < 0) { + log_fatal(logger, MODULE_FRAMEWORK_GTEST, + "[%s:%d] write config to redis failed.", + __FUNCTION__, __LINE__); + } + + struct maat_options *opts = maat_options_new(); + maat_options_set_redis(opts, redis_ip, redis_port, redis_db); + maat_options_set_stat_file(opts, "./stat.log"); + maat_options_set_logger(opts, "./maat_framework_gtest.log", LOG_LEVEL_INFO); + maat_options_set_accept_tags(opts, accept_tags); + maat_options_set_hit_path_enabled(opts); + + _shared_maat_inst = maat_new(opts, table_info_path); + maat_options_free(opts); + if (NULL == _shared_maat_inst) { + log_fatal(logger, MODULE_FRAMEWORK_GTEST, + "[%s:%d] create maat instance in TableSchemaTag failed.", + __FUNCTION__, __LINE__); + } + } + + static void TearDownTestCase() { + maat_free(_shared_maat_inst); + log_handle_destroy(logger); + } + + static struct log_handle *logger; + static struct maat *_shared_maat_inst; +}; + +struct maat *TableSchemaTag::_shared_maat_inst; +struct log_handle *TableSchemaTag::logger; + +TEST_F(TableSchemaTag, CompileTable) { + const char *compile1_table_name = "COMPILE_DEFAULT"; + const char *compile2_table_name = "COMPILE_ALIAS"; + const char *compile3_table_name = "COMPILE_CONJUNCTION"; + const char *g2c_table_name = "GROUP2COMPILE"; + struct maat *maat_inst = TableSchemaTag::_shared_maat_inst; + + //COMPILE_DEFAULT + int compile1_table_id = maat_get_table_id(maat_inst, compile1_table_name); + EXPECT_EQ(compile1_table_id, 0); + + const char *tag1 = maat_get_table_schema_tag(maat_inst, compile1_table_id); + EXPECT_TRUE(tag1 == NULL); + + //COMPILE_ALIAS + int compile2_table_id = maat_get_table_id(maat_inst, compile2_table_name); + EXPECT_EQ(compile2_table_id, 1); + + const char *tag2 = maat_get_table_schema_tag(maat_inst, compile2_table_id); + EXPECT_TRUE(tag2 != NULL); + + int ret = strcmp(tag2, "{\"compile_alias\": \"compile\"}"); + EXPECT_EQ(ret, 0); + + //COMPILE_CONJUNCTION + int compile3_table_id = maat_get_table_id(maat_inst, compile3_table_name); + EXPECT_EQ(compile3_table_id, 2); + + const char *tag3 = maat_get_table_schema_tag(maat_inst, compile3_table_id); + EXPECT_TRUE(tag3 != NULL); + + ret = strcmp(tag3, "{\"compile_conjunction\": \"compile\"}"); + EXPECT_EQ(ret, 0); + + //GROUP2COMPILE + int g2c_table_id = maat_get_table_id(maat_inst, g2c_table_name); + EXPECT_EQ(g2c_table_id, 3); + + const char *tag4 = maat_get_table_schema_tag(maat_inst, g2c_table_id); + EXPECT_TRUE(tag4 != NULL); + + ret = strcmp(tag4, "{\"group2compile\": \"group2compile\"}"); + EXPECT_EQ(ret, 0); + + //COMPILE_PLUGIN + const char *plugin_table_name = "COMPILE_PLUGIN"; + int plugin_table_id = maat_get_table_id(maat_inst, plugin_table_name); + EXPECT_EQ(plugin_table_id, 8); + + const char *tag5 = maat_get_table_schema_tag(maat_inst, plugin_table_id); + EXPECT_TRUE(tag5 != NULL); + + ret = strcmp(tag5, "{\"compile_plugin\": \"plugin\"}"); + EXPECT_EQ(ret, 0); + + //HTTP_REGION + const char *region_table_name = "HTTP_REGION"; + const char *url_table_name = "HTTP_URL"; + const char *host_table_name = "HTTP_HOST"; + + int region_table_id = maat_get_table_id(maat_inst, region_table_name); + EXPECT_EQ(region_table_id, 10); + + int url_table_id = maat_get_table_id(maat_inst, url_table_name); + EXPECT_EQ(url_table_id, 10); + + int host_table_id = maat_get_table_id(maat_inst, host_table_name); + EXPECT_EQ(host_table_id, 10); + + const char *tag6 = maat_get_table_schema_tag(maat_inst, region_table_id); + EXPECT_TRUE(tag6 != NULL); + + ret = strcmp(tag6, "{\"http_region\": \"expr\"}"); + EXPECT_EQ(ret, 0); + + //HTTP_RESPONSE_KEYWORDS + const char *vtable_name = "HTTP_RESPONSE_KEYWORDS"; + int vtable_id = maat_get_table_id(maat_inst, vtable_name); + EXPECT_EQ(vtable_id, 25); + + const char *tag7 = maat_get_table_schema_tag(maat_inst, vtable_id); + EXPECT_TRUE(tag7 != NULL); + + ret = strcmp(tag7, "{\"http_response_keywords\": \"virtual\"}"); + EXPECT_EQ(ret, 0); + + //VIRTUAL_IP_PLUS_TABLE + const char *vtable1_name = "VIRTUAL_IP_PLUS_TABLE"; + int vtable1_id = maat_get_table_id(maat_inst, vtable1_name); + EXPECT_EQ(vtable1_id, 28); + + const char *vtable2_name = "VIRTUAL_IP_PLUS_SOURCE"; + int vtable2_id = maat_get_table_id(maat_inst, vtable2_name); + EXPECT_EQ(vtable2_id, 28); + + const char *vtable3_name = "VIRTUAL_IP_PLUS_DESTINATION"; + int vtable3_id = maat_get_table_id(maat_inst, vtable3_name); + EXPECT_EQ(vtable3_id, 28); + + const char *tag8 = maat_get_table_schema_tag(maat_inst, vtable1_id); + EXPECT_TRUE(tag8 != NULL); + + ret = strcmp(tag8, "{\"virtual_ip_plus_table\": \"virtual\"}"); + EXPECT_EQ(ret, 0); +} + class CompileTable : public testing::Test { protected: @@ -6065,11 +6217,9 @@ TEST_F(CompileTable, CompileRuleUpdate) { MAAT_OP_ADD, compile_id, "null", 1, 0); EXPECT_EQ(ret, 1); - sleep(WAIT_FOR_EFFECTIVE_S); ret = compile_table_set_line(maat_inst, compile_table_name, MAAT_OP_DEL, compile_id, "null", 1, 0); EXPECT_EQ(ret, 1); - sleep(WAIT_FOR_EFFECTIVE_S); } TEST_F(CompileTable, Conjunction1) { diff --git a/test/table_info.conf b/test/table_info.conf index e16361e..01969dc 100644 --- a/test/table_info.conf +++ b/test/table_info.conf @@ -15,6 +15,7 @@ "table_name":"COMPILE_ALIAS", "table_type":"compile", "valid_column":9, + "schema_tag": "{\"compile_alias\": \"compile\"}", "custom": { "compile_id":1, "tags":6, @@ -28,6 +29,7 @@ "default_compile_table":2, "table_type":"compile", "valid_column":9, + "schema_tag": "{\"compile_conjunction\": \"compile\"}", "custom": { "compile_id":1, "tags":6, @@ -41,6 +43,7 @@ "table_type":"group2compile", "associated_compile_table_id":2, "valid_column":6, + "schema_tag": "{\"group2compile\": \"group2compile\"}", "custom": { "group_id":1, "compile_id":2, @@ -103,6 +106,7 @@ "db_tables":["COMPILE_DEFAULT", "COMPILE_ALIAS"], "table_type":"plugin", "valid_column":8, + "schema_tag": "{\"compile_plugin\": \"plugin\"}", "custom": { "gc_timeout_s":3, "key_type":"integer", @@ -130,6 +134,7 @@ "table_type":"expr", "expr_engine":"rulescan", "valid_column":7, + "schema_tag": "{\"http_region\": \"expr\"}", "custom": { "item_id":1, "group_id":2, @@ -340,7 +345,8 @@ "table_id":25, "table_name":"HTTP_RESPONSE_KEYWORDS", "table_type":"virtual", - "physical_table": "KEYWORDS_TABLE" + "physical_table": "KEYWORDS_TABLE", + "schema_tag": "{\"http_response_keywords\": \"virtual\"}" }, { "table_id":26, @@ -359,7 +365,8 @@ "table_name":"VIRTUAL_IP_PLUS_TABLE", "db_tables":["VIRTUAL_IP_PLUS_SOURCE", "VIRTUAL_IP_PLUS_DESTINATION"], "table_type":"virtual", - "physical_table": "IP_PLUS_CONFIG" + "physical_table": "IP_PLUS_CONFIG", + "schema_tag": "{\"virtual_ip_plus_table\": \"virtual\"}" }, { "table_id":29,