Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
KEP-770 Add protobuf status message support
Browse files Browse the repository at this point in the history
  • Loading branch information
ebruck committed Nov 6, 2018
1 parent 7f3d5a5 commit e9301d1
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ scripts/bluzelle_pb2.py
scripts/database_pb2.py
scripts/audit_pb2.py
scripts/pbft_pb2.py
scripts/status_pb2.py
*.pyc
*.pem
2 changes: 1 addition & 1 deletion proto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
protobuf_generate_cpp(PROTO_SRC PROTO_HEADER bluzelle.proto database.proto pbft.proto audit.proto)
protobuf_generate_cpp(PROTO_SRC PROTO_HEADER bluzelle.proto database.proto pbft.proto audit.proto status.proto)
add_library(proto ${PROTO_HEADER} ${PROTO_SRC})
set_target_properties(proto PROPERTIES COMPILE_FLAGS "-Wno-unused")
set(PROTO_INCLUDE_DIR ${CMAKE_BINARY_DIR}/proto)
5 changes: 4 additions & 1 deletion proto/bluzelle.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ syntax = "proto3";
import "database.proto";
import "audit.proto";
import "pbft.proto";
import "status.proto";

message bzn_msg
{
Expand All @@ -27,6 +28,7 @@ message bzn_msg
audit_message audit_message = 12;
pbft_msg pbft = 13;
pbft_membership_msg membership = 14;
status_request status = 15;
}
}

Expand All @@ -35,11 +37,12 @@ enum bzn_msg_type
BZN_MSG_UNDEFINED = 0;
BZN_MSG_PBFT = 1;
BZN_MSG_PBFT_MEMBERSHIP = 2;
BZN_STATUS_REQUEST = 3; // for now until wrapped_bzn_msg is refactored
}

message wrapped_bzn_msg
{
// This is stored as a serialized string because we need to sign it, and serialization is not guarenteed to be deterministic
// This is stored as a serialized string because we need to sign it, and serialization is not guaranteed to be deterministic
bytes payload = 1;
bzn_msg_type type = 2;

Expand Down
42 changes: 42 additions & 0 deletions proto/status.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2018 Bluzelle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

syntax = "proto3";

message status_request {}

message status_response
{
string swarm_version = 1;
string swarm_git_commit = 2;
string uptime = 3;
string module_status_json = 4;
bool pbft_enabled = 5;
}

message bzn_envelope
{
string sender = 1;
bytes signature = 2;

oneof payload
{
bytes pbft_request = 3;
bytes database_response = 4;
bytes json = 5;
bytes audit = 6;
bytes pbft = 7;
bytes pbft_membership = 8;
}
}
27 changes: 26 additions & 1 deletion scripts/crud
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ try:
import bluzelle_pb2
import database_pb2
import pbft_pb2
import status_pb2
except ImportError as e:
raise ImportError("{}\n\nTo generate Bluzelle protobuf modules:\n"
"\n"
Expand Down Expand Up @@ -169,20 +170,44 @@ def size_request():
msg.db.size.SetInParent()
return msg


def subscribe_request(key):
msg = bluzelle_pb2.bzn_msg()
msg.db.subscribe.key = key
return msg


def unsubscribe_request(key):
global transaction_id
msg = bluzelle_pb2.bzn_msg()
msg.db.unsubscribe.key = key
msg.db.unsubscribe.transaction_id = transaction_id
return msg


def status_handler(args):
return send_status_request(args.node)
global use_pbft

if not use_pbft:
return send_status_request(args.node)

ws = websocket.create_connection("ws://" + args.node)
msg_outer = bluzelle_pb2.wrapped_bzn_msg()
msg_outer.type = 3 # BZN_MSG_STATUS_REQUEST
msg_inner = status_pb2.status_request()
msg_outer.payload = msg_inner.SerializeToString()

print("Sending: \n{}".format(msg_outer).expandtabs(4))
ws.send_binary(msg_outer.SerializeToString())
resp = status_pb2.status_response()
resp.ParseFromString(ws.recv())

print("Response: \n{}".format(resp).expandtabs(4))
modules = json.loads(resp.module_status_json)
print("{}".format(json.dumps(modules,indent=4)))
print("-" * 60 + '\n')

return resp


def create_handler(args):
Expand Down
2 changes: 1 addition & 1 deletion status/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ add_library(status STATIC
status.hpp
)

target_link_libraries(status )
target_link_libraries(status proto)
add_dependencies(status jsoncpp proto)
target_include_directories(status PRIVATE ${JSONCPP_INCLUDE_DIRS})

Expand Down
59 changes: 49 additions & 10 deletions status/status.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <status/status.hpp>
#include <swarm_version.hpp>
#include <swarm_git_commit.hpp>
#include <proto/status.pb.h>

using namespace bzn;

Expand All @@ -27,6 +28,7 @@ namespace
const std::string MODULE_KEY{"module"};
const std::string UPTIME_KEY{"uptime"};
const std::string COMMIT_KEY{"commit"};
const std::string PBFT_ENABLED_KEY{"pbft_enabled"};

std::string get_uptime(const std::chrono::steady_clock::time_point& start_time)
{
Expand All @@ -46,10 +48,11 @@ namespace
}


status::status(std::shared_ptr<bzn::node_base> node, bzn::status::status_provider_list_t&& status_providers)
status::status(std::shared_ptr<bzn::node_base> node, bzn::status::status_provider_list_t&& status_providers, const bool pbft_enabled)
: node(std::move(node))
, status_providers(std::move(status_providers))
, start_time(std::chrono::steady_clock::now())
, pbft_enabled(pbft_enabled)
{
}

Expand All @@ -65,19 +68,20 @@ status::start()
{
throw std::runtime_error("Unable to register for STATUS messages!");
}

if (!this->node->register_for_message(bzn_msg_type::BZN_STATUS_REQUEST,
std::bind(&status::handle_status_request_message, shared_from_this(), std::placeholders::_1, std::placeholders::_2)))
{
throw std::runtime_error("Unable to register for STATUS REQUEST messages!");
}
});
}


void
status::handle_ws_status_messages(const bzn::json_message& ws_msg, std::shared_ptr<bzn::session_base> session)
bzn::json_message
status::query_modules()
{
auto response_msg = std::make_shared<bzn::json_message>(ws_msg);

(*response_msg)[VERSION_KEY] = SWARM_VERSION;
(*response_msg)[COMMIT_KEY] = SWARM_GIT_COMMIT;
(*response_msg)[UPTIME_KEY] = get_uptime(this->start_time);
(*response_msg)[MODULE_KEY] = bzn::json_message();
Json::Value module_status;

for (const auto& provider : this->status_providers)
{
Expand All @@ -88,11 +92,46 @@ status::handle_ws_status_messages(const bzn::json_message& ws_msg, std::shared_p
entry[NAME_KEY] = provider_shared_ptr->get_name();
entry[STATUS_KEY] = provider_shared_ptr->get_status();

(*response_msg)[MODULE_KEY].append(entry);
module_status.append(entry);
}
}

return module_status;
}


void
status::handle_ws_status_messages(const bzn::json_message& ws_msg, std::shared_ptr<bzn::session_base> session)
{
auto response_msg = std::make_shared<bzn::json_message>(ws_msg);

(*response_msg)[VERSION_KEY] = SWARM_VERSION;
(*response_msg)[COMMIT_KEY] = SWARM_GIT_COMMIT;
(*response_msg)[UPTIME_KEY] = get_uptime(this->start_time);
(*response_msg)[MODULE_KEY] = this->query_modules();
(*response_msg)[PBFT_ENABLED_KEY] = this->pbft_enabled;

LOG(debug) << response_msg->toStyledString().substr(0, MAX_MESSAGE_SIZE);

session->send_message(response_msg, false);
}


void
status::handle_status_request_message(const wrapped_bzn_msg& /*msg*/, std::shared_ptr<bzn::session_base> session)
{
status_response srm;

srm.set_swarm_version(SWARM_VERSION);
srm.set_swarm_git_commit(SWARM_GIT_COMMIT);
srm.set_uptime(get_uptime(this->start_time));
srm.set_pbft_enabled(this->pbft_enabled);

Json::Value module_status;
module_status[MODULE_KEY] = this->query_modules();
srm.set_module_status_json(module_status.toStyledString());

LOG(debug) << srm.DebugString().substr(0, MAX_MESSAGE_SIZE);

session->send_message(std::make_shared<bzn::encoded_message>(srm.SerializeAsString()), false);
}
8 changes: 7 additions & 1 deletion status/status.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,25 @@ namespace bzn
public:
using status_provider_list_t = std::vector<std::weak_ptr<bzn::status_provider_base>>;

status(std::shared_ptr<bzn::node_base> node, status_provider_list_t&& status_providers);
status(std::shared_ptr<bzn::node_base> node, status_provider_list_t&& status_providers, bool pbft_enabled);

void start();

private:
void handle_ws_status_messages(const bzn::json_message& ws_msg, std::shared_ptr<bzn::session_base> session);

void handle_status_request_message(const wrapped_bzn_msg& msg, std::shared_ptr<bzn::session_base> session);

bzn::json_message query_modules();

std::shared_ptr<bzn::node_base> node;

status_provider_list_t status_providers;
std::once_flag start_once;

const std::chrono::steady_clock::time_point start_time;

const bool pbft_enabled;
};

} // namespace bzn
2 changes: 1 addition & 1 deletion status/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(test_srcs status_test.cpp)
set(test_libs status )
set(test_libs status ${Protobuf_LIBRARIES})

add_gmock_test(status)

0 comments on commit e9301d1

Please sign in to comment.