This is an automated email from the ASF dual-hosted git repository.
laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git
The following commit(s) were added to refs/heads/master by this push:
new 2fe716b5e feat: add rename_app interface (#1272)
2fe716b5e is described below
commit 2fe716b5ef4f714412ebf27ed39a827d6a8769fd
Author: liguohao <[email protected]>
AuthorDate: Wed Dec 14 19:53:44 2022 +0800
feat: add rename_app interface (#1272)
---
idl/meta_admin.thrift | 12 +++++
src/client/replication_ddl_client.cpp | 20 ++++++++
src/client/replication_ddl_client.h | 3 ++
src/common/replication.codes.h | 1 +
src/meta/meta_rpc_types.h | 2 +
src/meta/meta_service.cpp | 14 ++++++
src/meta/meta_service.h | 1 +
src/meta/server_state.cpp | 79 +++++++++++++++++++++++++++++++
src/meta/server_state.h | 1 +
src/meta/test/meta_app_operation_test.cpp | 44 +++++++++++++++++
src/replica/replica.h | 1 +
src/replica/replica_config.cpp | 19 ++++++++
src/shell/commands.h | 2 +
src/shell/commands/table_management.cpp | 37 +++++++++++++++
src/shell/main.cpp | 3 ++
15 files changed, 239 insertions(+)
diff --git a/idl/meta_admin.thrift b/idl/meta_admin.thrift
index 9db6758db..fd29a2a77 100644
--- a/idl/meta_admin.thrift
+++ b/idl/meta_admin.thrift
@@ -166,6 +166,18 @@ struct configuration_drop_app_response
1:dsn.error_code err;
}
+struct configuration_rename_app_request
+{
+ 1:string old_app_name;
+ 2:string new_app_name;
+}
+
+struct configuration_rename_app_response
+{
+ 1:dsn.error_code err;
+ 2:string hint_message;
+}
+
struct configuration_recall_app_request
{
1:i32 app_id;
diff --git a/src/client/replication_ddl_client.cpp
b/src/client/replication_ddl_client.cpp
index 406b9d073..63e275484 100644
--- a/src/client/replication_ddl_client.cpp
+++ b/src/client/replication_ddl_client.cpp
@@ -53,6 +53,15 @@
namespace dsn {
namespace replication {
+#define VALIDATE_TABLE_NAME(app_name)
\
+ do {
\
+ if (app_name.empty() ||
\
+ !std::all_of(app_name.cbegin(),
\
+ app_name.cend(),
\
+ (bool
(*)(int))replication_ddl_client::valid_app_char)) \
+ return FMT_ERR(ERR_INVALID_PARAMETERS, "Invalid name. Only
0-9a-zA-Z.:_ are valid!"); \
+ } while (false)
+
using tp_output_format = ::dsn::utils::table_printer::output_format;
replication_ddl_client::replication_ddl_client(const
std::vector<dsn::rpc_address> &meta_servers)
@@ -1740,5 +1749,16 @@ replication_ddl_client::set_max_replica_count(const
std::string &app_name,
configuration_set_max_replica_count_rpc(std::move(req),
RPC_CM_SET_MAX_REPLICA_COUNT));
}
+error_with<configuration_rename_app_response>
+replication_ddl_client::rename_app(const std::string &old_app_name, const
std::string &new_app_name)
+{
+ VALIDATE_TABLE_NAME(old_app_name);
+ VALIDATE_TABLE_NAME(new_app_name);
+
+ auto req = std::make_unique<configuration_rename_app_request>();
+ req->__set_old_app_name(old_app_name);
+ req->__set_new_app_name(new_app_name);
+ return call_rpc_sync(configuration_rename_app_rpc(std::move(req),
RPC_CM_RENAME_APP));
+}
} // namespace replication
} // namespace dsn
diff --git a/src/client/replication_ddl_client.h
b/src/client/replication_ddl_client.h
index 5b562f7bb..f3350f5fe 100644
--- a/src/client/replication_ddl_client.h
+++ b/src/client/replication_ddl_client.h
@@ -72,6 +72,9 @@ public:
dsn::error_code recall_app(int32_t app_id, const std::string
&new_app_name);
+ error_with<configuration_rename_app_response> rename_app(const std::string
&old_app_name,
+ const std::string
&new_app_name);
+
dsn::error_code list_apps(const dsn::app_status::type status,
bool show_all,
bool detailed,
diff --git a/src/common/replication.codes.h b/src/common/replication.codes.h
index c39a969d4..73df12497 100644
--- a/src/common/replication.codes.h
+++ b/src/common/replication.codes.h
@@ -93,6 +93,7 @@ MAKE_EVENT_CODE_RPC(RPC_CM_UPDATE_PARTITION_CONFIGURATION,
TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_CREATE_APP, TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_DROP_APP, TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_RECALL_APP, TASK_PRIORITY_COMMON)
+MAKE_EVENT_CODE_RPC(RPC_CM_RENAME_APP, TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_LIST_APPS, TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_LIST_NODES, TASK_PRIORITY_COMMON)
MAKE_EVENT_CODE_RPC(RPC_CM_CLUSTER_INFO, TASK_PRIORITY_COMMON)
diff --git a/src/meta/meta_rpc_types.h b/src/meta/meta_rpc_types.h
index 746158915..7044e09b9 100644
--- a/src/meta/meta_rpc_types.h
+++ b/src/meta/meta_rpc_types.h
@@ -68,6 +68,8 @@ typedef
rpc_holder<configuration_get_max_replica_count_request,
typedef rpc_holder<configuration_set_max_replica_count_request,
configuration_set_max_replica_count_response>
configuration_set_max_replica_count_rpc;
+typedef rpc_holder<configuration_rename_app_request,
configuration_rename_app_response>
+ configuration_rename_app_rpc;
} // namespace replication
} // namespace dsn
diff --git a/src/meta/meta_service.cpp b/src/meta/meta_service.cpp
index 176b811a4..9b1de0997 100644
--- a/src/meta/meta_service.cpp
+++ b/src/meta/meta_service.cpp
@@ -401,6 +401,8 @@ void meta_service::register_rpc_handlers()
register_rpc_handler(RPC_CM_CREATE_APP, "create_app",
&meta_service::on_create_app);
register_rpc_handler(RPC_CM_DROP_APP, "drop_app",
&meta_service::on_drop_app);
register_rpc_handler(RPC_CM_RECALL_APP, "recall_app",
&meta_service::on_recall_app);
+ register_rpc_handler_with_rpc_holder(
+ RPC_CM_RENAME_APP, "rename_app", &meta_service::on_rename_app);
register_rpc_handler_with_rpc_holder(
RPC_CM_LIST_APPS, "list_apps", &meta_service::on_list_apps);
register_rpc_handler_with_rpc_holder(
@@ -527,6 +529,18 @@ void meta_service::on_drop_app(dsn::message_ex *req)
server_state::sStateHash);
}
+void meta_service::on_rename_app(configuration_rename_app_rpc rpc)
+{
+ if (!check_status(rpc)) {
+ return;
+ }
+
+ tasking::enqueue(LPC_META_STATE_NORMAL,
+ tracker(),
+ std::bind(&server_state::rename_app, _state.get(), rpc),
+ server_state::sStateHash);
+}
+
void meta_service::on_recall_app(dsn::message_ex *req)
{
configuration_recall_app_response response;
diff --git a/src/meta/meta_service.h b/src/meta/meta_service.h
index 3cfb23518..f41819cb9 100644
--- a/src/meta/meta_service.h
+++ b/src/meta/meta_service.h
@@ -194,6 +194,7 @@ private:
void on_create_app(dsn::message_ex *req);
void on_drop_app(dsn::message_ex *req);
void on_recall_app(dsn::message_ex *req);
+ void on_rename_app(configuration_rename_app_rpc rpc);
void on_list_apps(configuration_list_apps_rpc rpc);
void on_list_nodes(configuration_list_nodes_rpc rpc);
diff --git a/src/meta/server_state.cpp b/src/meta/server_state.cpp
index 558acb53b..475504f29 100644
--- a/src/meta/server_state.cpp
+++ b/src/meta/server_state.cpp
@@ -1259,6 +1259,85 @@ void server_state::drop_app(dsn::message_ex *msg)
}
}
+void server_state::rename_app(configuration_rename_app_rpc rpc)
+{
+ auto &response = rpc.response();
+ bool do_rename = false;
+
+ const auto &old_app_name = rpc.request().old_app_name;
+ const auto &new_app_name = rpc.request().new_app_name;
+ LOG_INFO_F(
+ "rename app request, old_app_name({}), new_app_name({})",
old_app_name, new_app_name);
+
+ zauto_write_lock l(_lock);
+ auto target_app = get_app(old_app_name);
+
+ if (target_app == nullptr) {
+ response.err = ERR_APP_NOT_EXIST;
+ response.hint_message = fmt::format("ERROR: app({}) not exist!",
old_app_name);
+ return;
+ }
+
+ switch (target_app->status) {
+ case app_status::AS_AVAILABLE: {
+ if (_exist_apps.find(new_app_name) != _exist_apps.end()) {
+ response.err = ERR_INVALID_PARAMETERS;
+ response.hint_message = fmt::format("ERROR: app({}) already
exist!", new_app_name);
+ return;
+ }
+ do_rename = true;
+ } break;
+ case app_status::AS_CREATING:
+ case app_status::AS_RECALLING: {
+ response.err = ERR_BUSY_CREATING;
+ } break;
+ case app_status::AS_DROPPING: {
+ response.err = ERR_BUSY_DROPPING;
+ } break;
+ case app_status::AS_DROPPED: {
+ response.err = ERR_APP_DROPPED;
+ } break;
+ default: {
+ response.err = ERR_INVALID_STATE;
+ } break;
+ }
+
+ if (!do_rename) {
+ response.hint_message =
+ fmt::format("ERROR: app({}) status can't execute rename.",
old_app_name);
+ return;
+ }
+
+ auto app_id = target_app->app_id;
+
+ auto ainfo = *(reinterpret_cast<app_info *>(target_app.get()));
+ ainfo.app_name = new_app_name;
+ auto app_path = get_app_path(*target_app);
+
+ target_app->app_name = new_app_name;
+ _exist_apps.emplace(new_app_name, target_app);
+
+ do_update_app_info(
+ app_path, ainfo, [this, app_id, new_app_name, old_app_name](error_code
ec) mutable {
+ CHECK_EQ_MSG(
+ ec,
+ ERR_OK,
+ "update remote app info failed: app_id={}, old_app_name={},
new_app_name={}",
+ app_id,
+ old_app_name,
+ new_app_name);
+
+ zauto_write_lock l(_lock);
+ _exist_apps.erase(old_app_name);
+
+ LOG_INFO_F("both remote and local app info of app_name have been
updated "
+ "successfully: app_id={}, old_app_name={},
new_app_name={}",
+ app_id,
+ old_app_name,
+ new_app_name);
+ });
+}
+
void server_state::do_app_recall(std::shared_ptr<app_state> &app)
{
auto after_recall_app = [this, app](dsn::error_code ec) mutable {
diff --git a/src/meta/server_state.h b/src/meta/server_state.h
index 374823a92..e761a42e0 100644
--- a/src/meta/server_state.h
+++ b/src/meta/server_state.h
@@ -144,6 +144,7 @@ public:
void create_app(dsn::message_ex *msg);
void drop_app(dsn::message_ex *msg);
void recall_app(dsn::message_ex *msg);
+ void rename_app(configuration_rename_app_rpc rpc);
void list_apps(const configuration_list_apps_request &request,
configuration_list_apps_response &response);
void restore_app(dsn::message_ex *msg);
diff --git a/src/meta/test/meta_app_operation_test.cpp
b/src/meta/test/meta_app_operation_test.cpp
index b9f034e32..33246addf 100644
--- a/src/meta/test/meta_app_operation_test.cpp
+++ b/src/meta/test/meta_app_operation_test.cpp
@@ -171,6 +171,20 @@ public:
return rpc.response();
}
+ configuration_rename_app_response rename_app(const std::string
&old_app_name,
+ const std::string
&new_app_name)
+ {
+ auto req = dsn::make_unique<configuration_rename_app_request>();
+ req->__set_old_app_name(old_app_name);
+ req->__set_new_app_name(new_app_name);
+
+ configuration_rename_app_rpc rpc(std::move(req), RPC_CM_RENAME_APP);
+ _ss->rename_app(rpc);
+ _ss->wait_all_task();
+
+ return rpc.response();
+ }
+
void set_app_and_all_partitions_max_replica_count(const std::string
&app_name,
int32_t
max_replica_count)
{
@@ -795,5 +809,35 @@ TEST_F(meta_app_operation_test,
recover_from_max_replica_count_env)
verify_app_max_replica_count(APP_NAME, new_max_replica_count);
}
+TEST_F(meta_app_operation_test, rename_app)
+{
+ const std::string app_name_1 = APP_NAME + "_rename_1";
+ create_app(app_name_1);
+ auto app = find_app(app_name_1);
+ ASSERT_TRUE(app) << fmt::format("app({}) does not exist", app_name_1);
+ auto app_id_1 = app->app_id;
+
+ const std::string app_name_2 = APP_NAME + "_rename_2";
+ create_app(app_name_2);
+ app = find_app(app_name_2);
+ ASSERT_TRUE(app) << fmt::format("app({}) does not exist", app_name_2);
+ auto app_id_2 = app->app_id;
+
+ // case 1: new_app_name table exist
+ auto resp = rename_app(app_name_1, app_name_2);
+ ASSERT_EQ(ERR_INVALID_PARAMETERS, resp.err);
+
+ const std::string app_name_3 = APP_NAME + "_rename_3";
+ // case 2: old_app_name table not exist
+ resp = rename_app(APP_NAME + "_rename_invaild", app_name_3);
+ ASSERT_EQ(ERR_APP_NOT_EXIST, resp.err);
+
+ // case 3: rename successful
+ resp = rename_app(app_name_1, app_name_3);
+ ASSERT_EQ(ERR_OK, resp.err);
+ app = find_app(app_name_3);
+ ASSERT_TRUE(app) << fmt::format("app({}) does not exist", app_name_3);
+ ASSERT_EQ(app_id_1, app->app_id);
+}
} // namespace replication
} // namespace dsn
diff --git a/src/replica/replica.h b/src/replica/replica.h
index 7c578f200..20c9877dd 100644
--- a/src/replica/replica.h
+++ b/src/replica/replica.h
@@ -496,6 +496,7 @@ private:
clear_on_failure(replica_stub *stub, replica *rep, const std::string
&path, const gpid &pid);
void update_app_max_replica_count(int32_t max_replica_count);
+ void update_app_name(const std::string &app_name);
private:
friend class ::dsn::replication::test::test_checker;
diff --git a/src/replica/replica_config.cpp b/src/replica/replica_config.cpp
index 47347813e..9f481b7a0 100644
--- a/src/replica/replica_config.cpp
+++ b/src/replica/replica_config.cpp
@@ -1029,6 +1029,7 @@ void replica::on_config_sync(const app_info &info,
return;
update_app_max_replica_count(info.max_replica_count);
+ update_app_name(info.app_name);
update_app_envs(info.envs);
_is_duplication_master = info.duplicating;
@@ -1070,6 +1071,24 @@ void replica::on_config_sync(const app_info &info,
}
}
+void replica::update_app_name(const std::string &app_name)
+{
+ if (app_name == _app_info.app_name) {
+ return;
+ }
+
+ auto old_app_name = _app_info.app_name;
+ _app_info.app_name = app_name;
+
+ CHECK_EQ_PREFIX_MSG(store_app_info(_app_info),
+ ERR_OK,
+ "store_app_info for app_name failed: "
+ "app_name={}, app_id={}, old_app_name={}",
+ _app_info.app_name,
+ _app_info.app_id,
+ old_app_name);
+}
+
void replica::update_app_max_replica_count(int32_t max_replica_count)
{
if (max_replica_count == _app_info.max_replica_count) {
diff --git a/src/shell/commands.h b/src/shell/commands.h
index 468532655..1245f1d3a 100644
--- a/src/shell/commands.h
+++ b/src/shell/commands.h
@@ -145,6 +145,8 @@ bool drop_app(command_executor *e, shell_context *sc,
arguments args);
bool recall_app(command_executor *e, shell_context *sc, arguments args);
+bool rename_app(command_executor *e, shell_context *sc, arguments args);
+
bool get_app_envs(command_executor *e, shell_context *sc, arguments args);
bool set_app_envs(command_executor *e, shell_context *sc, arguments args);
diff --git a/src/shell/commands/table_management.cpp
b/src/shell/commands/table_management.cpp
index f78a9a755..b9a6871e8 100644
--- a/src/shell/commands/table_management.cpp
+++ b/src/shell/commands/table_management.cpp
@@ -721,6 +721,43 @@ bool drop_app(command_executor *e, shell_context *sc,
arguments args)
return true;
}
+bool rename_app(command_executor *e, shell_context *sc, arguments args)
+{
+ if (args.argc <= 2) {
+ return false;
+ }
+
+ const std::string old_app_name = args.argv[1];
+ const std::string new_app_name = args.argv[2];
+
+ auto err_resp = sc->ddl_client->rename_app(old_app_name, new_app_name);
+ auto err = err_resp.get_error();
+ const auto &resp = err_resp.get_value();
+
+ if (dsn_likely(err.is_ok())) {
+ err = dsn::error_s::make(resp.err);
+ }
+
+ if (err.is_ok()) {
+ fmt::print(stdout,
+ "rename app ok, old_app_name({}), new_app_name({})\n",
+ old_app_name,
+ new_app_name);
+ } else {
+ std::string error_message(resp.err.to_string());
+ if (!resp.hint_message.empty()) {
+ error_message += ", ";
+ error_message += resp.hint_message;
+ }
+ fmt::print(stderr,
+ "rename app failed, old_app_name({}), new_app_name({}),
failed: {}\n",
+ old_app_name,
+ new_app_name,
+ error_message);
+ }
+ return true;
+}
+
bool recall_app(command_executor *e, shell_context *sc, arguments args)
{
if (args.argc <= 1)
diff --git a/src/shell/main.cpp b/src/shell/main.cpp
index d58340cf1..766f5d863 100644
--- a/src/shell/main.cpp
+++ b/src/shell/main.cpp
@@ -91,6 +91,9 @@ static command_executor commands[] = {
{
"recall", "recall an app", "<app_id> [new_app_name]", recall_app,
},
+ {
+ "rename", "rename an app", "<old_app_name> <new_app_name>", rename_app,
+ },
{
"set_meta_level",
"set the meta function level: stopped, blind, freezed, steady, lively",
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]