Skip to content

Commit

Permalink
fix meta http replace host handler (vesoft-inc#3794)
Browse files Browse the repository at this point in the history
* fix meta http replace host handler

* fix http replace test and add zone test

Co-authored-by: Sophie <[email protected]>
  • Loading branch information
2 people authored and liwenhui-soul committed Jan 29, 2022
1 parent 05a9f34 commit 349d56b
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 84 deletions.
67 changes: 54 additions & 13 deletions src/meta/http/MetaHttpReplaceHostHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,20 @@ void MetaHttpReplaceHostHandler::onRequest(std::unique_ptr<HTTPMessage> headers)

if (!headers->hasQueryParam("from")) {
err_ = HttpCode::E_ILLEGAL_ARGUMENT;
errMsg_ = "miss argument [from]";
errMsg_ = "Miss argument [from]";
return;
}

if (!headers->hasQueryParam("to")) {
err_ = HttpCode::E_ILLEGAL_ARGUMENT;
errMsg_ = "miss argument [to]";
errMsg_ = "Miss argument [to]";
return;
}

ipv4From_ = headers->getQueryParam("from");

ipv4To_ = headers->getQueryParam("to");

LOG(INFO) << folly::sformat("change host info from {} to {}", ipv4From_, ipv4To_);
LOG(INFO) << folly::sformat("Change host info from {} to {}", ipv4From_, ipv4To_);
}

void MetaHttpReplaceHostHandler::onBody(std::unique_ptr<folly::IOBuf>) noexcept {
Expand All @@ -76,15 +75,15 @@ void MetaHttpReplaceHostHandler::onEOM() noexcept {
break;
}

if (replaceHost(ipv4From_, ipv4To_)) {
LOG(INFO) << "Replace Host successfully";
if (replaceHostInPart(ipv4From_, ipv4To_) && replaceHostInZone(ipv4From_, ipv4To_)) {
LOG(INFO) << "Replace Host in partition and zone successfully";
ResponseBuilder(downstream_)
.status(WebServiceUtils::to(HttpStatusCode::OK),
WebServiceUtils::toString(HttpStatusCode::OK))
.body("Replace Host successfully")
.body("Replace Host in partition and zone successfully")
.sendWithEOM();
} else {
LOG(INFO) << "Replace Host failed";
LOG(INFO) << "Replace Host in partition and zone failed";
ResponseBuilder(downstream_)
.status(WebServiceUtils::to(HttpStatusCode::FORBIDDEN),
WebServiceUtils::toString(HttpStatusCode::FORBIDDEN))
Expand All @@ -106,13 +105,13 @@ void MetaHttpReplaceHostHandler::onError(ProxygenError error) noexcept {
<< proxygen::getErrorString(error);
}

bool MetaHttpReplaceHostHandler::replaceHost(std::string ipv4From, std::string ipv4To) {
bool MetaHttpReplaceHostHandler::replaceHostInPart(std::string ipv4From, std::string ipv4To) {
folly::SharedMutex::WriteHolder wHolder(LockUtils::spaceLock());
const auto& spacePrefix = MetaKeyUtils::spacePrefix();
std::unique_ptr<kvstore::KVIterator> iter;
auto kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, spacePrefix, &iter);
if (kvRet != nebula::cpp2::ErrorCode::SUCCEEDED) {
errMsg_ = folly::stringPrintf("can't get space prefix=%s", spacePrefix.c_str());
errMsg_ = folly::stringPrintf("Can't get space prefix=%s", spacePrefix.c_str());
LOG(INFO) << errMsg_;
return false;
}
Expand All @@ -123,14 +122,14 @@ bool MetaHttpReplaceHostHandler::replaceHost(std::string ipv4From, std::string i
allSpaceId.emplace_back(spaceId);
iter->next();
}
LOG(INFO) << "allSpaceId.size()=" << allSpaceId.size();
LOG(INFO) << "AllSpaceId.size()=" << allSpaceId.size();

std::vector<nebula::kvstore::KV> data;
for (const auto& spaceId : allSpaceId) {
const auto& partPrefix = MetaKeyUtils::partPrefix(spaceId);
kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, partPrefix, &iter);
if (kvRet != nebula::cpp2::ErrorCode::SUCCEEDED) {
errMsg_ = folly::stringPrintf("can't get partPrefix=%s", partPrefix.c_str());
errMsg_ = folly::stringPrintf("Can't get partPrefix=%s", partPrefix.c_str());
LOG(INFO) << errMsg_;
return false;
}
Expand All @@ -156,12 +155,54 @@ bool MetaHttpReplaceHostHandler::replaceHost(std::string ipv4From, std::string i
kvstore_->asyncMultiPut(
kDefaultSpaceId, kDefaultPartId, std::move(data), [&](nebula::cpp2::ErrorCode code) {
updateSucceed = (code == nebula::cpp2::ErrorCode::SUCCEEDED);
errMsg_ = folly::stringPrintf("write to kvstore failed, %s , %d", __func__, __LINE__);
errMsg_ = folly::stringPrintf("Write to kvstore failed, %s , %d", __func__, __LINE__);
baton.post();
});
baton.wait();
return updateSucceed;
}

bool MetaHttpReplaceHostHandler::replaceHostInZone(std::string ipv4From, std::string ipv4To) {
folly::SharedMutex::WriteHolder wHolder(LockUtils::spaceLock());
const auto& zonePrefix = MetaKeyUtils::zonePrefix();
std::unique_ptr<kvstore::KVIterator> iter;
auto kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, zonePrefix, &iter);
if (kvRet != nebula::cpp2::ErrorCode::SUCCEEDED) {
errMsg_ = folly::stringPrintf("Can't get zone prefix=%s", zonePrefix.c_str());
LOG(INFO) << errMsg_;
return false;
}

std::vector<nebula::kvstore::KV> data;
while (iter->valid()) {
bool needUpdate = false;
auto zoneName = MetaKeyUtils::parseZoneName(iter->key());
auto hosts = MetaKeyUtils::parseZoneHosts(iter->val());
for (auto& host : hosts) {
if (host.host == ipv4From) {
host.host = ipv4To;
needUpdate = true;
}
}

if (needUpdate) {
data.emplace_back(iter->key(), MetaKeyUtils::zoneVal(hosts));
}
iter->next();
}

bool updateSucceed{false};
folly::Baton<true, std::atomic> baton;
kvstore_->asyncMultiPut(
kDefaultSpaceId, kDefaultPartId, std::move(data), [&](nebula::cpp2::ErrorCode code) {
updateSucceed = (code == nebula::cpp2::ErrorCode::SUCCEEDED);
errMsg_ = folly::stringPrintf("Write to kvstore failed, %s , %d", __func__, __LINE__);
baton.post();
});
baton.wait();

return updateSucceed;
}

} // namespace meta
} // namespace nebula
11 changes: 6 additions & 5 deletions src/meta/http/MetaHttpReplaceHostHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ using nebula::HttpCode;
/**
* @brief It will replace host info in meta partition table from
* backup host to current cluster host.
* It should be called after ingesting meta sst files when
* restore cluster.
* It will replace given host in zone table and partition table. Notice that,
* it only replace the host without port.
* Functions such as onRequest, onBody... and requestComplete are inherited
* from RequestHandler, we will check request parameters in onRequest and
* call main logic in onEOM.
Expand All @@ -33,7 +33,7 @@ class MetaHttpReplaceHostHandler : public proxygen::RequestHandler {
public:
MetaHttpReplaceHostHandler() = default;

void init(nebula::kvstore::KVStore *kvstore);
void init(nebula::kvstore::KVStore* kvstore);

void onRequest(std::unique_ptr<proxygen::HTTPMessage> headers) noexcept override;

Expand All @@ -47,14 +47,15 @@ class MetaHttpReplaceHostHandler : public proxygen::RequestHandler {

void onError(proxygen::ProxygenError error) noexcept override;

bool replaceHost(std::string ipv4From, std::string ipv4To);
bool replaceHostInPart(std::string ipv4From, std::string ipv4To);
bool replaceHostInZone(std::string ipv4From, std::string ipv4To);

private:
HttpCode err_{HttpCode::SUCCEEDED};
std::string errMsg_;
std::string ipv4From_;
std::string ipv4To_;
nebula::kvstore::KVStore *kvstore_;
nebula::kvstore::KVStore* kvstore_;
};

} // namespace meta
Expand Down
32 changes: 16 additions & 16 deletions src/meta/http/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ nebula_add_test(
)


# nebula_add_test(
# NAME
# meta_http_replace_test
# SOURCES
# MetaHttpReplaceHandlerTest.cpp
# OBJECTS
# $<TARGET_OBJECTS:storage_http_handler>
# $<TARGET_OBJECTS:meta_http_handler>
# ${meta_test_deps}
# LIBRARIES
# ${ROCKSDB_LIBRARIES}
# ${THRIFT_LIBRARIES}
# ${PROXYGEN_LIBRARIES}
# wangle
# gtest
# )
nebula_add_test(
NAME
meta_http_replace_test
SOURCES
MetaHttpReplaceHandlerTest.cpp
OBJECTS
$<TARGET_OBJECTS:storage_http_handler>
$<TARGET_OBJECTS:meta_http_handler>
${meta_test_deps}
LIBRARIES
${ROCKSDB_LIBRARIES}
${THRIFT_LIBRARIES}
${PROXYGEN_LIBRARIES}
wangle
gtest
)
Loading

0 comments on commit 349d56b

Please sign in to comment.