Skip to content

Commit

Permalink
feat(fqdn): json decode & encode for rpc_host_port (#1811)
Browse files Browse the repository at this point in the history
Issue: #1810

Implement json_decode & json_encode for class `rpc_host_port`.
  • Loading branch information
GehaFearless authored Dec 27, 2023
1 parent 1b44329 commit 4e66ebe
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/common/json_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,21 @@ inline bool json_decode(const dsn::json::JsonObject &in, dsn::rpc_address &addre
return address.from_string_ipv4(rpc_address_string.c_str());
}

// json serialization for rpc host_port, we use the string representation of a host_port
inline void json_encode(JsonWriter &out, const dsn::host_port &hp)
{
json_encode(out, hp.to_string());
}
inline bool json_decode(const dsn::json::JsonObject &in, dsn::host_port &hp)
{
std::string host_port_string;
dverify(json_decode(in, host_port_string));
if (host_port_string == "invalid host_port") {
return true;
}
return hp.from_string(host_port_string);
}

inline void json_encode(JsonWriter &out, const dsn::partition_configuration &config);
inline bool json_decode(const JsonObject &in, dsn::partition_configuration &config);
inline void json_encode(JsonWriter &out, const dsn::app_info &info);
Expand Down
30 changes: 28 additions & 2 deletions src/runtime/rpc/rpc_host_port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
#include "runtime/rpc/group_host_port.h"
#include "runtime/rpc/rpc_host_port.h"
#include "utils/error_code.h"
#include "utils/ports.h"
#include "utils/safe_strerror_posix.h"
#include "utils/string_conv.h"
#include "utils/utils.h"

namespace dsn {
Expand All @@ -57,7 +59,6 @@ error_s GetAddrInfo(const std::string &hostname, const addrinfo &hints, AddrInfo
if (info != nullptr) {
info->swap(result);
}

return error_s::ok();
}
}
Expand All @@ -73,7 +74,7 @@ host_port::host_port(rpc_address addr)
switch (addr.type()) {
case HOST_TYPE_IPV4: {
CHECK(utils::hostname_from_ip(htonl(addr.ip()), &_host),
"invalid address {}",
"invalid host_port {}",
addr.ipv4_str());
_port = addr.port();
} break;
Expand All @@ -86,6 +87,31 @@ host_port::host_port(rpc_address addr)
_type = addr.type();
}

bool host_port::from_string(const std::string &s)
{
const auto pos = s.find_last_of(':');
if (dsn_unlikely(pos == std::string::npos)) {
return false;
}
_host = s.substr(0, pos);
std::string port = s.substr(pos + 1);

if (dsn_unlikely(!dsn::buf2uint16(port, _port))) {
return false;
}

struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (dsn_unlikely(!GetAddrInfo(_host, hints, nullptr))) {
return false;
}

_type = HOST_TYPE_IPV4;
return true;
}

void host_port::reset()
{
switch (type()) {
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/rpc/rpc_host_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class host_port
// Resolve host_port to rpc_addresses.
// Trere may be multiple rpc_addresses for one host_port.
error_s resolve_addresses(std::vector<rpc_address> &addresses) const;
// This function is used for validating the format of string like "localhost:8888".
bool from_string(const std::string &s);

// for serialization in thrift format
uint32_t read(::apache::thrift::protocol::TProtocol *iprot);
Expand Down
13 changes: 13 additions & 0 deletions src/runtime/test/host_port_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ TEST(host_port_test, operators)
ASSERT_NE(hp, hp2);
ASSERT_FALSE(hp.is_invalid());
ASSERT_TRUE(hp2.is_invalid());

std::string hp_str = "localhost:8080";
host_port hp3;
ASSERT_TRUE(hp3.is_invalid());
ASSERT_TRUE(hp3.from_string(hp_str));
ASSERT_EQ(hp, hp3);
ASSERT_FALSE(hp3.is_invalid());

host_port hp4;
ASSERT_TRUE(hp4.is_invalid());
std::string hp_str2 = "pegasus:8080";
ASSERT_FALSE(hp4.from_string(hp_str2));
ASSERT_TRUE(hp4.is_invalid());
}

TEST(host_port_test, rpc_group_host_port)
Expand Down
5 changes: 5 additions & 0 deletions src/utils/string_conv.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ inline bool buf2uint64(absl::string_view buf, uint64_t &result)
return internal::buf2unsigned(buf, result);
}

inline bool buf2uint16(absl::string_view buf, uint16_t &result)
{
return internal::buf2unsigned(buf, result);
}

inline bool buf2bool(absl::string_view buf, bool &result, bool ignore_case = true)
{
std::string data(buf.data(), buf.length());
Expand Down
11 changes: 11 additions & 0 deletions src/utils/test/json_helper_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

#include "common/json_helper.h"
#include "gtest/gtest.h"
#include "runtime/rpc/rpc_host_port.h"
#include "utils/blob.h"

namespace dsn {
Expand Down Expand Up @@ -505,4 +506,14 @@ TEST(json_helper, upgrade_downgrade)
ASSERT_EQ(n2.c, o.c);
}

TEST(json_helper, host_port_encode_decode)
{
dsn::host_port hp("localhost", 8888);
dsn::blob bb = dsn::json::json_forwarder<decltype(hp)>::encode(hp);
dsn::host_port hp2;
dsn::json::json_forwarder<dsn::host_port>::decode(bb, hp2);

ASSERT_EQ(hp, hp2);
}

} // namespace dsn

0 comments on commit 4e66ebe

Please sign in to comment.