Skip to content

Commit ff4c7c0

Browse files
committed
refactor grpc: disallow constructing SimpleClientComponent of non-generated clients
This was an accidentally allowed hack. `samples/grpc_service` shows how to create custom gRPC client wrappers if needed. commit_hash:eac2884a8429cf8672dbbcb3b129a195f470134e
1 parent e64efb2 commit ff4c7c0

File tree

6 files changed

+41
-25
lines changed

6 files changed

+41
-25
lines changed

otlp/src/otlp/logs/logger.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ Logger::Logger(
214214
trace_client = std::move(trace_client)]() mutable {
215215
SendingLoop(consumer, log_client, trace_client);
216216
});
217-
;
218217
}
219218

220219
Logger::~Logger() { Stop(); }

samples/grpc_service/src/call_greeter_client_test_handler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class CallGreeterClientTestHandler final : public server::handlers::HttpHandlerB
1818

1919
CallGreeterClientTestHandler(const components::ComponentConfig& config, const components::ComponentContext& context)
2020
: HttpHandlerBase(config, context),
21-
grpc_greeter_client_(context.FindComponent<GreeterClientComponent>().GetClient()) {}
21+
grpc_greeter_client_(context.FindComponent<GreeterClientComponent>().GetClientWrapper()) {}
2222

2323
std::string HandleRequest(server::http::HttpRequest& request, server::request::RequestContext&) const override {
2424
const auto& arg_case = request.GetArg("case");

samples/grpc_service/src/greeter_client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const USERVER_NAMESPACE::dynamic_config::Key<ugrpc::client::ClientQos> kGreeterC
2525

2626
// A user-defined wrapper around api::GreeterServiceClient that provides
2727
// a simplified interface.
28-
GreeterClient::GreeterClient(api::GreeterServiceClient&& raw_client) : raw_client_(std::move(raw_client)) {}
28+
GreeterClient::GreeterClient(api::GreeterServiceClient& raw_client) : raw_client_(raw_client) {}
2929

3030
/// [client]
3131
std::string GreeterClient::SayHello(std::string name) const {

samples/grpc_service/src/greeter_client.hpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace samples {
2727
// microservice. Ignore that, it's just for the sake of example.
2828
class GreeterClient final {
2929
public:
30-
explicit GreeterClient(api::GreeterServiceClient&& raw_client);
30+
explicit GreeterClient(api::GreeterServiceClient& raw_client);
3131

3232
std::string SayHello(std::string name) const;
3333

@@ -37,12 +37,10 @@ class GreeterClient final {
3737

3838
std::vector<std::string> SayHelloStreams(const std::vector<std::string_view>& names) const;
3939

40-
static std::optional<ugrpc::impl::StaticServiceMetadata> GetMetadata() { return std::nullopt; }
41-
4240
private:
4341
static ugrpc::client::CallOptions MakeCallOptions();
4442

45-
api::GreeterServiceClient raw_client_;
43+
api::GreeterServiceClient& raw_client_;
4644
};
4745
/// [client]
4846

@@ -51,16 +49,21 @@ using Client = GreeterClient;
5149
/// [component]
5250
extern const USERVER_NAMESPACE::dynamic_config::Key<ugrpc::client::ClientQos> kGreeterClientQos;
5351

54-
class GreeterClientComponent final : public ugrpc::client::SimpleClientComponent<Client> {
52+
class GreeterClientComponent final : public ugrpc::client::SimpleClientComponent<api::GreeterServiceClient> {
5553
public:
5654
static constexpr std::string_view kName = "greeter-client";
5755

58-
using Base = ugrpc::client::SimpleClientComponent<Client>;
56+
using Base = ugrpc::client::SimpleClientComponent<api::GreeterServiceClient>;
5957

6058
GreeterClientComponent(const ::components::ComponentConfig& config, const ::components::ComponentContext& context)
61-
: Base(config, context, kGreeterClientQos) {}
59+
: Base(config, context, kGreeterClientQos), client_wrapper_(GetClient()) {}
6260

6361
using Base::GetClient;
62+
63+
GreeterClient& GetClientWrapper() noexcept { return client_wrapper_; }
64+
65+
private:
66+
GreeterClient client_wrapper_;
6467
};
6568
/// [component]
6669

samples/grpc_service/unittests/greeter_service_test.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,30 @@ class GreeterServiceTest : public ugrpc::tests::ServiceFixtureBase {
1717
GreeterServiceTest() : service_(prefix_) {
1818
RegisterService(service_);
1919
StartServer();
20+
generated_client_ = MakeClient<samples::api::GreeterServiceClient>();
2021
}
2122

2223
~GreeterServiceTest() override { StopServer(); }
2324

25+
samples::api::GreeterServiceClient& GetGeneratedClient() { return generated_client_.value(); }
26+
2427
private:
2528
const std::string prefix_{"Hello"};
2629
// We've made sure to separate the logic into samples::GreeterService that is
2730
// detached from the component system and only depends on things obtainable
2831
// in gtest tests.
2932
samples::GreeterService service_;
33+
34+
std::optional<samples::api::GreeterServiceClient> generated_client_;
3035
};
3136
/// [service fixture]
3237
} // namespace
3338

3439
/// [service tests]
3540
UTEST_F(GreeterServiceTest, SayHelloDirectCall) {
36-
const auto client = MakeClient<samples::api::GreeterServiceClient>();
37-
3841
samples::api::GreetingRequest request;
3942
request.set_name("gtest");
40-
const auto response = client.SayHello(request);
43+
const auto response = GetGeneratedClient().SayHello(request);
4144

4245
EXPECT_EQ(response.greeting(), "Hello, gtest!");
4346
}
@@ -46,15 +49,15 @@ UTEST_F(GreeterServiceTest, SayHelloCustomClient) {
4649
// We've made sure to separate some logic into samples::GreeterClient that is
4750
// detached from the component system, it only needs the gRPC client, which we
4851
// can create in gtest tests.
49-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
52+
const samples::GreeterClient client{GetGeneratedClient()};
5053
const auto response = client.SayHello("gtest");
5154
EXPECT_EQ(response, "Hello, gtest!");
5255
}
5356
/// [service tests]
5457

5558
/// [service tests response stream]
5659
UTEST_F(GreeterServiceTest, SayHelloResponseStreamCustomClient) {
57-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
60+
const samples::GreeterClient client{GetGeneratedClient()};
5861
const auto responses = client.SayHelloResponseStream("gtest");
5962
EXPECT_THAT(
6063
responses,
@@ -67,7 +70,7 @@ UTEST_F(GreeterServiceTest, SayHelloResponseStreamCustomClient) {
6770

6871
/// [service tests request stream]
6972
UTEST_F(GreeterServiceTest, SayHelloRequestStreamCustomClient) {
70-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
73+
const samples::GreeterClient client{GetGeneratedClient()};
7174

7275
const std::vector<std::string_view> names = {"gtest", "!", "!", "!"};
7376
const auto response = client.SayHelloRequestStream(names);
@@ -78,7 +81,7 @@ UTEST_F(GreeterServiceTest, SayHelloRequestStreamCustomClient) {
7881

7982
/// [service tests streams]
8083
UTEST_F(GreeterServiceTest, SayHelloStreamsCustomClient) {
81-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
84+
const samples::GreeterClient client{GetGeneratedClient()};
8285

8386
const std::vector<std::string_view> names = {"gtest", "!", "!", "!"};
8487
const auto responses = client.SayHelloStreams(names);
@@ -102,18 +105,26 @@ class GreeterMock final : public samples::api::GreeterServiceBase {
102105
::samples::api::GreetingRequest&& request,
103106
SayHelloResponseStreamWriter& writer
104107
) override;
108+
105109
SayHelloRequestStreamResult SayHelloRequestStream(CallContext& context, SayHelloRequestStreamReader& reader)
106110
override;
111+
107112
SayHelloStreamsResult SayHelloStreams(CallContext& context, SayHelloStreamsReaderWriter& stream) override;
108113
};
109114

110115
// Default-constructs GreeterMock.
111-
using GreeterClientTest = ugrpc::tests::ServiceFixture<GreeterMock>;
116+
class GreeterClientTest : public ugrpc::tests::ServiceFixture<GreeterMock> {
117+
protected:
118+
samples::api::GreeterServiceClient& GetGeneratedClient() { return generated_client_; }
119+
120+
private:
121+
samples::api::GreeterServiceClient generated_client_{MakeClient<samples::api::GreeterServiceClient>()};
122+
};
112123

113124
} // namespace
114125

115126
UTEST_F(GreeterClientTest, SayHelloMockedServiceCustomClient) {
116-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
127+
const samples::GreeterClient client{GetGeneratedClient()};
117128
const auto response = client.SayHello("gtest");
118129
EXPECT_EQ(response, "Mocked response");
119130
}
@@ -138,7 +149,7 @@ GreeterMock::SayHelloResponseStreamResult GreeterMock::SayHelloResponseStream(
138149
}
139150

140151
UTEST_F(GreeterClientTest, SayHelloResponseStreamMockedServiceCustomClient) {
141-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
152+
const samples::GreeterClient client{GetGeneratedClient()};
142153
const auto responses = client.SayHelloResponseStream("gtest");
143154
EXPECT_THAT(
144155
responses,
@@ -161,7 +172,7 @@ GreeterMock::SayHelloRequestStream(CallContext& /*context*/, SayHelloRequestStre
161172
}
162173

163174
UTEST_F(GreeterClientTest, SayHelloRequestStreamMockedServiceCustomClient) {
164-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
175+
const samples::GreeterClient client{GetGeneratedClient()};
165176
const std::vector<std::string_view> names = {"gtest", "!", "!", "!"};
166177
auto response = client.SayHelloRequestStream(names);
167178
EXPECT_EQ(response, "Mocked response!!!");
@@ -183,7 +194,7 @@ GreeterMock::SayHelloStreams(CallContext& /*context*/, SayHelloStreamsReaderWrit
183194
}
184195

185196
UTEST_F(GreeterClientTest, SayHelloStreamsMockedServiceCustomClient) {
186-
const samples::GreeterClient client{MakeClient<samples::api::GreeterServiceClient>()};
197+
const samples::GreeterClient client{GetGeneratedClient()};
187198

188199
const std::vector<std::string_view> names = {"gtest", "!", "!", "!"};
189200
const auto responses = client.SayHelloStreams(names);

scripts/grpc/templates/client.usrv.hpp.jinja

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ public:
7272

7373
/// @cond
7474
// For internal use only
75-
{{service.name}}Client(USERVER_NAMESPACE::ugrpc::client::impl::ClientInternals&& internals);
75+
explicit {{service.name}}Client(USERVER_NAMESPACE::ugrpc::client::impl::ClientInternals&& internals);
7676

77+
// For internal use only
7778
static USERVER_NAMESPACE::ugrpc::impl::StaticServiceMetadata GetMetadata();
7879
/// @endcond
7980

@@ -142,9 +143,11 @@ public:
142143

143144
/// @cond
144145
// For internal use only
145-
{{service.name}}Client(
146-
USERVER_NAMESPACE::utils::SharedRef<{{namespace_path}}::{{service.name}}Client> protobuf_client);
146+
explicit {{service.name}}Client(
147+
USERVER_NAMESPACE::utils::SharedRef<{{namespace_path}}::{{service.name}}Client> protobuf_client
148+
);
147149

150+
// For internal use only
148151
static USERVER_NAMESPACE::ugrpc::impl::StaticServiceMetadata GetMetadata();
149152
/// @endcond
150153

0 commit comments

Comments
 (0)