Skip to content

Commit 07c279f

Browse files
committed
Add some grpc helpers.
1 parent 66348a2 commit 07c279f

8 files changed

Lines changed: 151 additions & 67 deletions

File tree

cppan.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,15 @@ projects:
235235
file(GLOB_RECURSE x "${SDIR}/*")
236236
source_group(TREE ${SDIR} PREFIX "Source Files" FILES ${x})
237237
238-
api_proto:
238+
protos:
239239
type: lib
240240
static_only: true
241-
custom: true
242-
root_directory: src/manager
243-
files: api.proto
241+
root_directory: src/protocol
242+
files: .*
244243
dependencies:
244+
- name: pvt.egorpugin.primitives.log
245+
version: master
246+
local: primitives.log
245247
- pvt.cppan.demo.google.protobuf.protoc: "*"
246248
- pvt.cppan.demo.google.protobuf.protobuf: "*"
247249
- pvt.cppan.demo.google.grpc.grpcpp: 1
@@ -279,7 +281,7 @@ projects:
279281
#- /wd4275 # non dll-interface used as base for dll-interface
280282

281283
dependencies:
282-
- api_proto
284+
- protos
283285
- support
284286
- name: pvt.egorpugin.primitives.tools.sqlpp11.sqlite2cpp
285287
version: master

src/client/client.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ bool bUseSystemPause = false;
5757
int main(int argc, char **argv);
5858
int main1(int argc, char **argv);
5959
int main_setup(int argc, char **argv);
60-
int cppan_main(int argc, char **argv);
60+
int sw_main(int argc, char **argv);
6161
void stop();
6262
void setup_log(const std::string &log_level);
6363
std::tuple<bool, std::string> parseCmd(int argc, char **argv);
@@ -167,6 +167,8 @@ int main1(int argc, char **argv)
167167
return r;
168168
}
169169

170+
#include <api.h>
171+
170172
int main_setup(int argc, char **argv)
171173
{
172174
#ifdef NDEBUG
@@ -177,10 +179,10 @@ int main_setup(int argc, char **argv)
177179

178180
getServiceDatabase();
179181

180-
return cppan_main(argc, argv);
182+
return sw_main(argc, argv);
181183
}
182184

183-
int cppan_main(int argc, char **argv)
185+
int sw_main(int argc, char **argv)
184186
{
185187
if (auto r = parseCmd(argc, argv); !std::get<0>(r))
186188
{

src/manager/api.cpp

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "remote.h"
1111
#include "settings.h"
1212

13+
#include <grpc_helpers.h>
14+
1315
#include <grpcpp/grpcpp.h>
1416

1517
#include <primitives/log.h>
@@ -30,16 +32,18 @@ void apply_auth(const Remote &r, grpc::ClientContext &context)
3032
context.AddMetadata("auth.token", r.token);
3133
}
3234

33-
void check_status(grpc::Status status)
35+
auto getContext()
3436
{
35-
if (!status.ok())
36-
LOG_ERROR(logger, "RPC failed: " << status.error_code() << ": " << status.error_message());
37+
auto ctx = std::make_unique<grpc::ClientContext>();
38+
ctx->AddMetadata("client.version", "0.3.0");
39+
return ctx;
3740
}
3841

39-
void check_status_and_throw(grpc::Status status)
42+
auto getContextWithAuth(const Remote &r)
4043
{
41-
if (!status.ok())
42-
throw std::runtime_error("RPC failed: " + std::to_string(status.error_code()) + ": " + status.error_message());
44+
auto ctx = getContext();
45+
apply_auth(r, *ctx);
46+
return ctx;
4347
}
4448

4549
Api::Api(const Remote &r)
@@ -54,15 +58,15 @@ void Api::addDownloads(const std::set<int64_t> &pkgs)
5458
api::PackageIds request;
5559
for (auto &id : pkgs)
5660
request.mutable_ids()->Add(id);
57-
grpc::ClientContext context;
58-
check_status(api_->AddDownloads(&context, request, nullptr));
61+
auto context = getContext();
62+
GRPC_CALL(api_, AddDownloads, google::protobuf::Empty);
5963
}
6064

6165
void Api::addClientCall()
6266
{
6367
google::protobuf::Empty request;
64-
grpc::ClientContext context;
65-
check_status(api_->AddClientCall(&context, request, nullptr));
68+
auto context = getContext();
69+
GRPC_CALL(api_, AddClientCall, google::protobuf::Empty);
6670
}
6771

6872
IdDependencies Api::resolvePackages(const UnresolvedPackages &pkgs)
@@ -74,12 +78,11 @@ IdDependencies Api::resolvePackages(const UnresolvedPackages &pkgs)
7478
pb_pkg->set_path(pkg.ppath);
7579
pb_pkg->set_range(pkg.range.toString());
7680
}
77-
api::ResolvedPackages resolved;
78-
grpc::ClientContext context;
79-
check_status_and_throw(api_->ResolvePackages(&context, request, &resolved));
81+
auto context = getContext();
82+
GRPC_CALL_THROWS(api_, ResolvePackages, api::ResolvedPackages);
8083

8184
IdDependencies id_deps;
82-
for (auto &pkg : resolved.packages())
85+
for (auto &pkg : response.packages())
8386
{
8487
DownloadDependency d;
8588
d.ppath = pkg.package().path();
@@ -90,7 +93,7 @@ IdDependencies Api::resolvePackages(const UnresolvedPackages &pkgs)
9093

9194
std::unordered_set<db::PackageVersionId> idx;
9295
for (auto &tree_dep : pkg.dependencies())
93-
idx.insert(tree_dep);
96+
idx.insert(tree_dep.id());
9497
d.setDependencyIds(idx);
9598
}
9699
return id_deps;
@@ -100,11 +103,8 @@ void Api::addVersion(const String &cppan)
100103
{
101104
api::NewPackage request;
102105
request.set_script(cppan);
103-
104-
grpc::ClientContext context;
105-
apply_auth(r, context);
106-
107-
check_status(user_->AddPackage(&context, request, nullptr));
106+
auto context = getContextWithAuth(r);
107+
GRPC_CALL(user_, AddPackage, google::protobuf::Empty);
108108
}
109109

110110
void Api::addVersion(PackagePath p, const Version &vnew, const optional<Version> &vold)
@@ -117,10 +117,8 @@ void Api::addVersion(PackagePath p, const Version &vnew, const optional<Version>
117117
if (vold)
118118
request.mutable_version()->set_old_version(vold.value().toString());
119119

120-
grpc::ClientContext context;
121-
apply_auth(r, context);
122-
123-
check_status(user_->AddPackage(&context, request, nullptr));
120+
auto context = getContextWithAuth(r);
121+
GRPC_CALL(user_, AddPackage, google::protobuf::Empty);
124122
}
125123

126124
void Api::updateVersion(PackagePath p, const Version &v)
@@ -134,10 +132,8 @@ void Api::updateVersion(PackagePath p, const Version &v)
134132
request.set_path(p.toString());
135133
request.set_version(v.toString());
136134

137-
grpc::ClientContext context;
138-
apply_auth(r, context);
139-
140-
check_status(user_->UpdatePackage(&context, request, nullptr));
135+
auto context = getContextWithAuth(r);
136+
GRPC_CALL(user_, UpdatePackage, google::protobuf::Empty);
141137
}
142138

143139
void Api::removeVersion(PackagePath p, const Version &v)
@@ -148,10 +144,8 @@ void Api::removeVersion(PackagePath p, const Version &v)
148144
request.set_path(p.toString());
149145
request.set_version(v.toString());
150146

151-
grpc::ClientContext context;
152-
apply_auth(r, context);
153-
154-
check_status(user_->UpdatePackage(&context, request, nullptr));
147+
auto context = getContextWithAuth(r);
148+
GRPC_CALL(user_, RemovePackage, google::protobuf::Empty);
155149
}
156150

157151
void Api::getNotifications(int n)
@@ -162,15 +156,12 @@ void Api::getNotifications(int n)
162156
api::NotificationsRequest request;
163157
request.set_n(n);
164158

165-
api::Notifications notifications;
166-
167-
grpc::ClientContext context;
168-
apply_auth(r, context);
169-
170-
check_status_and_throw(user_->GetNotifications(&context, request, &notifications));
159+
auto context = getContextWithAuth(r);
160+
GRPC_CALL_THROWS(user_, GetNotifications, api::Notifications);
171161

162+
// move out; return as result
172163
int i = 1;
173-
for (auto &n : notifications.notifications())
164+
for (auto &n : response.notifications())
174165
{
175166
auto nt = (NotificationType)n.type();
176167
std::ostringstream ss;
@@ -197,8 +188,8 @@ void Api::getNotifications(int n)
197188
void Api::clearNotifications()
198189
{
199190
google::protobuf::Empty request;
200-
grpc::ClientContext context;
201-
check_status(user_->ClearNotification(&context, request, nullptr));
191+
auto context = getContextWithAuth(r);
192+
GRPC_CALL(user_, ClearNotification, google::protobuf::Empty);
202193
}
203194

204195
}

src/manager/api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "package.h"
1313

1414
#undef ERROR
15-
#include "api.grpc.pb.h"
15+
#include <api.grpc.pb.h>
1616

1717
namespace sw
1818
{

src/manager/remote.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,25 +100,18 @@ String Remote::github_source_provider(const Package &d) const
100100
return "https://github.com/cppan-packages/" + d.getHash() + "/raw/master/" + make_archive_name();
101101
}
102102

103-
std::shared_ptr<grpc::Channel> Remote::getGrpcChannel()
103+
std::shared_ptr<grpc::Channel> Remote::getGrpcChannel() const
104104
{
105105
if (!channel)
106106
{
107107
auto p = url.find("://");
108108
auto host = url.substr(p == url.npos ? 0 : p + 3);
109109
host = host.substr(0, host.find('/'));
110110

111-
auto creds = grpc::InsecureChannelCredentials();
112-
if (host.find("localhost") != 0)
113-
{
114-
grpc::SslCredentialsOptions ssl_options;
115-
ssl_options.pem_root_certs = read_file("server.crt");
116-
117-
creds = grpc::SslCredentials(ssl_options);
118-
}
119-
else
120-
host = "https://localhost/";
111+
grpc::SslCredentialsOptions ssl_options;
112+
ssl_options.pem_root_certs = read_file("server.crt");
121113

114+
auto creds = grpc::SslCredentials(ssl_options);
122115
channel = grpc::CreateChannel(host, creds);
123116
}
124117
return channel;
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,19 @@ message UnresolvedPackages {
2727

2828
message ResolvedPackages {
2929
message ResolvedPackage {
30+
message Dependency {
31+
int64 id = 1;
32+
// if package is deployed on a private server
33+
// string path?
34+
// flags?
35+
}
36+
// base fields
3037
int64 id = 1;
3138
PackageId package = 2;
3239
int64 flags = 3;
3340
string hash = 4;
34-
repeated int64 dependencies = 5;
41+
repeated Dependency dependencies = 5;
42+
// other
3543
int64 group_number = 16;
3644
// int32 archive_type;
3745
}
@@ -84,11 +92,12 @@ service ApiService {
8492
// get_version_hash
8593
}
8694

95+
// id: 1
8796
service UserService {
88-
rpc AddPackage (NewPackage) returns (google.protobuf.Empty);
89-
rpc UpdatePackage (PackageId) returns (google.protobuf.Empty);
90-
rpc RemovePackage (PackageId) returns (google.protobuf.Empty);
97+
rpc AddPackage (NewPackage) returns (google.protobuf.Empty); // id: 1
98+
rpc UpdatePackage (PackageId) returns (google.protobuf.Empty); // id: 2
99+
rpc RemovePackage (PackageId) returns (google.protobuf.Empty); // id: 3
91100

92-
rpc GetNotifications (NotificationsRequest) returns (Notifications);
93-
rpc ClearNotification (google.protobuf.Empty) returns (google.protobuf.Empty);
101+
rpc GetNotifications (NotificationsRequest) returns (Notifications); // id: 4
102+
rpc ClearNotification (google.protobuf.Empty) returns (google.protobuf.Empty); // id: 5
94103
}

src/protocol/grpc_helpers.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "grpc_helpers.h"
2+
3+
#include <primitives/log.h>
4+
DECLARE_STATIC_LOGGER(logger, "protocol");
5+
6+
namespace sw
7+
{
8+
9+
// namespace api?
10+
11+
CallResult check_result(
12+
const grpc::Status &status,
13+
const grpc::ClientContext &context,
14+
const std::string &method,
15+
bool throws
16+
)
17+
{
18+
CallResult r;
19+
20+
if (!status.ok())
21+
{
22+
auto err = "Method '" + method + "': RPC failed: " + std::to_string(status.error_code()) + ": " + status.error_message();
23+
if (throws)
24+
throw std::runtime_error(err);
25+
else
26+
LOG_ERROR(logger, err);
27+
r.ec = std::make_error_code((std::errc)status.error_code());
28+
r.message = status.error_message();
29+
return r;
30+
}
31+
32+
auto result = get_metadata_variable(context.GetServerTrailingMetadata(), "ec");
33+
auto ec = std::stoi(result.data());
34+
if (ec)
35+
{
36+
auto message = get_metadata_variable(context.GetServerTrailingMetadata(), "message");
37+
auto err = "Method '" + method + "' returned error: ec = " + result + ", message:" + message;
38+
if (throws)
39+
throw std::runtime_error(err);
40+
else
41+
LOG_ERROR(logger, err);
42+
r.ec = std::make_error_code((std::errc)ec);
43+
r.message = message;
44+
}
45+
46+
return r;
47+
}
48+
49+
std::string get_metadata_variable(const std::multimap<grpc::string_ref, grpc::string_ref> &m, const std::string &key)
50+
{
51+
auto i = m.find(key);
52+
if (i == m.end())
53+
return {};
54+
return i->second.data();
55+
}
56+
57+
}

src/protocol/grpc_helpers.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include <grpcpp/impl/codegen/client_context.h>
4+
#include <grpcpp/impl/codegen/status.h>
5+
6+
#define GRPC_CALL_INTERNAL(svc, m, resptype, t) \
7+
resptype response; \
8+
check_result(svc->m(context.get(), request, &response), *context, #m, t)
9+
#define GRPC_CALL(svc, m, resptype) GRPC_CALL_INTERNAL(svc, m, resptype, false)
10+
#define GRPC_CALL_THROWS(svc, m, resptype) GRPC_CALL_INTERNAL(svc, m, resptype, true)
11+
12+
namespace sw
13+
{
14+
15+
struct CallResult
16+
{
17+
std::error_code ec;
18+
std::string message;
19+
};
20+
21+
CallResult check_result(
22+
const grpc::Status &status,
23+
const grpc::ClientContext &context,
24+
const std::string &method,
25+
bool throws = false
26+
);
27+
28+
std::string get_metadata_variable(const std::multimap<grpc::string_ref, grpc::string_ref> &metadata, const std::string &key);
29+
30+
}

0 commit comments

Comments
 (0)