From 4719d634cd80bdfb6244def5940245ddfda85ada Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Mon, 11 May 2020 10:48:31 +0800 Subject: [PATCH 01/11] [schema] Add table definitions required by dynamic buffer calculation Signed-off-by: Stephen Sun --- common/schema.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/common/schema.h b/common/schema.h index 9b59e1e09..528c139b2 100644 --- a/common/schema.h +++ b/common/schema.h @@ -87,6 +87,13 @@ namespace swss { #define APP_MACSEC_EGRESS_SA_TABLE_NAME "MACSEC_EGRESS_SA_TABLE" #define APP_MACSEC_INGRESS_SA_TABLE_NAME "MACSEC_INGRESS_SA_TABLE" +#define APP_BUFFER_POOL_TABLE_NAME "BUFFER_POOL" +#define APP_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE" +#define APP_BUFFER_PG_TABLE_NAME "BUFFER_PG" +#define APP_BUFFER_QUEUE_TABLE_NAME "BUFFER_QUEUE" +#define APP_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME "BUFFER_PORT_INGRESS_PROFILE_LIST" +#define APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME "BUFFER_PORT_EGRESS_PROFILE_LIST" + /***** TO BE REMOVED *****/ #define APP_TC_TO_QUEUE_MAP_TABLE_NAME "TC_TO_QUEUE_MAP_TABLE" @@ -99,13 +106,6 @@ namespace swss { #define APP_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_NAME "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_TABLE" #define APP_PFC_PRIORITY_TO_QUEUE_MAP_NAME "MAP_PFC_PRIORITY_TO_QUEUE" -#define APP_BUFFER_POOL_TABLE_NAME "BUFFER_POOL_TABLE" -#define APP_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE_TABLE" -#define APP_BUFFER_QUEUE_TABLE_NAME "BUFFER_QUEUE_TABLE" -#define APP_BUFFER_PG_TABLE_NAME "BUFFER_PG_TABLE" -#define APP_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME "BUFFER_PORT_INGRESS_PROFILE_LIST" -#define APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME "BUFFER_PORT_EGRESS_PROFILE_LIST" - /***** COUNTER DATABASE *****/ #define COUNTERS_PORT_NAME_MAP "COUNTERS_PORT_NAME_MAP" @@ -241,6 +241,8 @@ namespace swss { #define CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME "BUFFER_PORT_INGRESS_PROFILE_LIST" #define CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME "BUFFER_PORT_EGRESS_PROFILE_LIST" +#define CFG_DEFAULT_LOSSLESS_BUFFER_PARAMETER "DEFAULT_LOSSLESS_BUFFER_PARAMETER" + #define CFG_POLICER_TABLE_NAME "POLICER" #define CFG_WARM_RESTART_TABLE_NAME "WARM_RESTART" @@ -342,6 +344,12 @@ namespace swss { #define STATE_MACSEC_EGRESS_SC_TABLE_NAME "MACSEC_EGRESS_SC_TABLE" #define STATE_MACSEC_EGRESS_SA_TABLE_NAME "MACSEC_EGRESS_SA_TABLE" +#define STATE_ASIC_TABLE "ASIC_TABLE" +#define STATE_BUFFER_MAXIMUM_VALUE_TABLE "BUFFER_MAX_PARAM" +#define STATE_PERIPHERAL_TABLE "PERIPHERAL_TABLE" +#define STATE_PORT_PERIPHERAL_TABLE "PORT_PERIPHERAL_TABLE" +#define STATE_BUFFER_POOL_TABLE_NAME "BUFFER_POOL" +#define STATE_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE" /***** MISC *****/ #define IPV4_NAME "IPv4" From 5d366f33faaa87684bf368dfb62feebc556ac041 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Tue, 2 Jun 2020 02:45:02 +0000 Subject: [PATCH 02/11] [json] Port json parser from swssconfig to swss-common so that other component can take advantage of this tool --- common/json.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ common/json.h | 8 +++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/common/json.cpp b/common/json.cpp index dd0c5e9f8..d1d4f7149 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -1,4 +1,7 @@ +#include #include +#include +#include #include #include "common/json.h" @@ -36,4 +39,63 @@ void JSon::readJson(const string &jsonstr, vector &fv) } } +bool JSon::loadJsonFromFile(ifstream &fs, vector &db_items) +{ + nlohmann::json json_array; + fs >> json_array; + + if (!json_array.is_array()) + { + SWSS_LOG_ERROR("Root element must be an array."); + return false; + } + + for (size_t i = 0; i < json_array.size(); i++) + { + auto &arr_item = json_array[i]; + + if (arr_item.is_object()) + { + if (el_count != arr_item.size()) + { + SWSS_LOG_ERROR("Chlid elements must have both key and op entry. %s", + arr_item.dump().c_str()); + return false; + } + + db_items.push_back(KeyOpFieldsValuesTuple()); + auto &cur_db_item = db_items[db_items.size() - 1]; + + for (nlohmann::json::iterator child_it = arr_item.begin(); child_it != arr_item.end(); child_it++) { + auto cur_obj_key = child_it.key(); + auto &cur_obj = child_it.value(); + + if (cur_obj.is_object()) { + kfvKey(cur_db_item) = cur_obj_key; + for (nlohmann::json::iterator cur_obj_it = cur_obj.begin(); cur_obj_it != cur_obj.end(); cur_obj_it++) + { + string field_str = cur_obj_it.key(); + string value_str; + if ((*cur_obj_it).is_number()) + value_str = to_string((*cur_obj_it).get()); + else if ((*cur_obj_it).is_string()) + value_str = (*cur_obj_it).get(); + kfvFieldsValues(cur_db_item).push_back(FieldValueTuple(field_str, value_str)); + } + } + else + { + kfvOp(cur_db_item) = cur_obj.get(); + } + } + } + else + { + SWSS_LOG_ERROR("Child elements must be objects. element:%s", arr_item.dump().c_str()); + return false; + } + } + return true; +} + } diff --git a/common/json.h b/common/json.h index ecd5d1520..da7798fd4 100644 --- a/common/json.h +++ b/common/json.h @@ -2,6 +2,7 @@ #define __JSON__ #include +#include #include #include "table.h" @@ -10,9 +11,12 @@ namespace swss { class JSon { +private: + static const int el_count = 2; public: - static std::string buildJson(const std::vector &fv); - static void readJson(const std::string &json, std::vector &fv); + static std::string buildJson(const std::vector &fv); + static void readJson(const std::string &json, std::vector &fv); + static bool loadJsonFromFile(std::ifstream &fs, std::vector &db_items); }; } From f5c06d03ce1abb6f4de45026d1693f2686f02db5 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Thu, 10 Sep 2020 11:05:16 +0800 Subject: [PATCH 03/11] Follow the name convention in APPL_DB and STATE_DB: add "_TABLE" suffix Signed-off-by: Stephen Sun --- common/schema.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/schema.h b/common/schema.h index 528c139b2..b67d4591d 100644 --- a/common/schema.h +++ b/common/schema.h @@ -87,12 +87,12 @@ namespace swss { #define APP_MACSEC_EGRESS_SA_TABLE_NAME "MACSEC_EGRESS_SA_TABLE" #define APP_MACSEC_INGRESS_SA_TABLE_NAME "MACSEC_INGRESS_SA_TABLE" -#define APP_BUFFER_POOL_TABLE_NAME "BUFFER_POOL" -#define APP_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE" -#define APP_BUFFER_PG_TABLE_NAME "BUFFER_PG" -#define APP_BUFFER_QUEUE_TABLE_NAME "BUFFER_QUEUE" -#define APP_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME "BUFFER_PORT_INGRESS_PROFILE_LIST" -#define APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME "BUFFER_PORT_EGRESS_PROFILE_LIST" +#define APP_BUFFER_POOL_TABLE_NAME "BUFFER_POOL_TABLE" +#define APP_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE_TABLE" +#define APP_BUFFER_PG_TABLE_NAME "BUFFER_PG_TABLE" +#define APP_BUFFER_QUEUE_TABLE_NAME "BUFFER_QUEUE_TABLE" +#define APP_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME "BUFFER_PORT_INGRESS_PROFILE_LIST_TABLE" +#define APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME "BUFFER_PORT_EGRESS_PROFILE_LIST_TABLE" /***** TO BE REMOVED *****/ @@ -345,11 +345,11 @@ namespace swss { #define STATE_MACSEC_EGRESS_SA_TABLE_NAME "MACSEC_EGRESS_SA_TABLE" #define STATE_ASIC_TABLE "ASIC_TABLE" -#define STATE_BUFFER_MAXIMUM_VALUE_TABLE "BUFFER_MAX_PARAM" +#define STATE_BUFFER_MAXIMUM_VALUE_TABLE "BUFFER_MAX_PARAM_TABLE" #define STATE_PERIPHERAL_TABLE "PERIPHERAL_TABLE" #define STATE_PORT_PERIPHERAL_TABLE "PORT_PERIPHERAL_TABLE" -#define STATE_BUFFER_POOL_TABLE_NAME "BUFFER_POOL" -#define STATE_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE" +#define STATE_BUFFER_POOL_TABLE_NAME "BUFFER_POOL_TABLE" +#define STATE_BUFFER_PROFILE_TABLE_NAME "BUFFER_PROFILE_TABLE" /***** MISC *****/ #define IPV4_NAME "IPv4" From 4d06910e0954b542f261329d588763b2c30e859a Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 4 Nov 2020 07:34:04 +0000 Subject: [PATCH 04/11] Fix typo and remove unnecessary sentence Signed-off-by: Stephen Sun --- common/json.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/common/json.cpp b/common/json.cpp index d1d4f7149..32147e6c5 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -58,7 +58,7 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite { if (el_count != arr_item.size()) { - SWSS_LOG_ERROR("Chlid elements must have both key and op entry. %s", + SWSS_LOG_ERROR("Child elements must have both key and op entry. %s", arr_item.dump().c_str()); return false; } @@ -83,10 +83,6 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite kfvFieldsValues(cur_db_item).push_back(FieldValueTuple(field_str, value_str)); } } - else - { - kfvOp(cur_db_item) = cur_obj.get(); - } } } else From d55b9b65976a666ba48849a680d0a7e5ad657622 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Mon, 16 Nov 2020 09:38:50 +0000 Subject: [PATCH 05/11] Add comments for the json interface Signed-off-by: Stephen Sun --- common/json.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/common/json.h b/common/json.h index da7798fd4..87f386058 100644 --- a/common/json.h +++ b/common/json.h @@ -12,10 +12,49 @@ namespace swss { class JSon { private: + /* + * el_count represents the number of elements in each object, + * which means each object have exactly 2 elements: the data and the operator + */ static const int el_count = 2; public: static std::string buildJson(const std::vector &fv); static void readJson(const std::string &json, std::vector &fv); + /* + bool loadJsonFromFile(std::ifstream &fs, std::vector &db_items); + + parse the json file and construct a vector of KeyOpFieldsValuesTuple as the result + the json file should be a list objects with each consisting of a data field and an operator field + - the data should be a dictionary + - the operator field should be a string, "SET" or "DEL" + an example: + [ + { + "QOS_TABLE:TC_TO_QUEUE_MAP_TABLE:AZURE": { + "5": "1", + "6": "1" + }, + "OP": "SET" + }, + { + "QOS_TABLE:DSCP_TO_TC_MAP_TABLE:AZURE": { + "7":"5", + "6":"5", + "3":"3", + "8":"7", + "9":"8" + }, + "OP": "SET" + } + ] + + parameters: + fs: the input ifstream representing the json file + fv: the output vector + return: boolean + True: the input json file has been succefully parsed + False: there are some errors found + */ static bool loadJsonFromFile(std::ifstream &fs, std::vector &db_items); }; From e37a6fb7ba073ec5622ae1526a00ea6457be3145 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Fri, 20 Nov 2020 05:51:09 +0000 Subject: [PATCH 06/11] Test whether op is "SET" during parsing json file --- common/json.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/common/json.cpp b/common/json.cpp index 32147e6c5..fe7b3af93 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -83,6 +83,17 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite kfvFieldsValues(cur_db_item).push_back(FieldValueTuple(field_str, value_str)); } } + else + { + auto op = cur_obj.get(); + if (op != "SET") + { + SWSS_LOG_ERROR("Child elements'op field must be SET, but got %s, ignored", op.c_str()); + db_items.pop_back(); + break; + } + kfvOp(cur_db_item) = op; + } } } else From ca706490664a44246bc8a84f8e4a7380a74a71b6 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Tue, 1 Dec 2020 00:45:51 +0000 Subject: [PATCH 07/11] Fix review comments Signed-off-by: Stephen Sun --- common/json.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/common/json.cpp b/common/json.cpp index fe7b3af93..cd2357eb0 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -63,14 +63,16 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite return false; } - db_items.push_back(KeyOpFieldsValuesTuple()); - auto &cur_db_item = db_items[db_items.size() - 1]; + db_items.emplace_back(KeyOpFieldsValuesTuple()); + auto &cur_db_item = db_items.back(); - for (nlohmann::json::iterator child_it = arr_item.begin(); child_it != arr_item.end(); child_it++) { + for (auto child_it = arr_item.begin(); child_it != arr_item.end(); child_it++) + { auto cur_obj_key = child_it.key(); auto &cur_obj = child_it.value(); - if (cur_obj.is_object()) { + if (cur_obj.is_object()) + { kfvKey(cur_db_item) = cur_obj_key; for (nlohmann::json::iterator cur_obj_it = cur_obj.begin(); cur_obj_it != cur_obj.end(); cur_obj_it++) { @@ -80,12 +82,13 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite value_str = to_string((*cur_obj_it).get()); else if ((*cur_obj_it).is_string()) value_str = (*cur_obj_it).get(); - kfvFieldsValues(cur_db_item).push_back(FieldValueTuple(field_str, value_str)); + kfvFieldsValues(cur_db_item).emplace_back(FieldValueTuple(field_str, value_str)); } } else { auto op = cur_obj.get(); + if (op != "SET") { SWSS_LOG_ERROR("Child elements'op field must be SET, but got %s, ignored", op.c_str()); From 096ac399f703263e4fe1db36c1685fc8cfe85ebe Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Tue, 1 Dec 2020 03:22:03 +0000 Subject: [PATCH 08/11] Fix review comments Signed-off-by: Stephen Sun --- common/json.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/common/json.cpp b/common/json.cpp index cd2357eb0..9356e7c42 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -42,7 +42,16 @@ void JSon::readJson(const string &jsonstr, vector &fv) bool JSon::loadJsonFromFile(ifstream &fs, vector &db_items) { nlohmann::json json_array; - fs >> json_array; + + try + { + fs >> json_array; + } + catch (...) + { + SWSS_LOG_ERROR("Unable to parse json from the input stream"); + return false; + } if (!json_array.is_array()) { @@ -63,7 +72,7 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite return false; } - db_items.emplace_back(KeyOpFieldsValuesTuple()); + db_items.emplace_back(); auto &cur_db_item = db_items.back(); for (auto child_it = arr_item.begin(); child_it != arr_item.end(); child_it++) @@ -82,16 +91,16 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite value_str = to_string((*cur_obj_it).get()); else if ((*cur_obj_it).is_string()) value_str = (*cur_obj_it).get(); - kfvFieldsValues(cur_db_item).emplace_back(FieldValueTuple(field_str, value_str)); + kfvFieldsValues(cur_db_item).emplace_back(field_str, value_str); } } else { auto op = cur_obj.get(); - if (op != "SET") + if (op != "SET" && op != "DEL") { - SWSS_LOG_ERROR("Child elements'op field must be SET, but got %s, ignored", op.c_str()); + SWSS_LOG_ERROR("Child elements' op field must be SET or DEL, but got %s, ignored", op.c_str()); db_items.pop_back(); break; } From 4d9b4b62ad6592f68bdf2ce3a8887fb111f6c981 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 2 Dec 2020 01:39:59 +0000 Subject: [PATCH 09/11] catch std::exceptions instead of ... and log the eception info Signed-off-by: Stephen Sun --- common/json.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/json.cpp b/common/json.cpp index 9356e7c42..ee1b96c1c 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -47,9 +47,9 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite { fs >> json_array; } - catch (...) + catch (const std::exception &e) { - SWSS_LOG_ERROR("Unable to parse json from the input stream"); + SWSS_LOG_ERROR("Unable to parse json from the input stream: %s", e.what()); return false; } From aac4639088cb36652ae232f4ab5ab3ba78f4ded6 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 2 Dec 2020 12:57:57 +0800 Subject: [PATCH 10/11] Break down the exception handling to catch more specific exceptions - logic_error for json syntax errors - bas_alloc for insufficient memory Signed-off-by: Stephen Sun --- common/json.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/json.cpp b/common/json.cpp index ee1b96c1c..6e712b49f 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -47,11 +47,16 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite { fs >> json_array; } - catch (const std::exception &e) + catch (const std::logic_error &e) { SWSS_LOG_ERROR("Unable to parse json from the input stream: %s", e.what()); return false; } + catch (const std::bad_alloc &e) + { + SWSS_LOG_ERROR("Unable to parse json from the imput stream: %s", e.what()); + return false; + } if (!json_array.is_array()) { From 1ebb3d3630569c3f5a533f81195301367dccec04 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 2 Dec 2020 06:34:46 +0000 Subject: [PATCH 11/11] Fix typo Signed-off-by: Stephen Sun --- common/json.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/json.cpp b/common/json.cpp index 6e712b49f..5541f7617 100644 --- a/common/json.cpp +++ b/common/json.cpp @@ -54,7 +54,7 @@ bool JSon::loadJsonFromFile(ifstream &fs, vector &db_ite } catch (const std::bad_alloc &e) { - SWSS_LOG_ERROR("Unable to parse json from the imput stream: %s", e.what()); + SWSS_LOG_ERROR("Unable to parse json from the input stream: %s", e.what()); return false; }