interop_server.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. *
  3. * Copyright 2015-2016 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <fstream>
  19. #include <memory>
  20. #include <sstream>
  21. #include <thread>
  22. #include "absl/flags/flag.h"
  23. #include <grpc/grpc.h>
  24. #include <grpc/support/log.h>
  25. #include <grpc/support/time.h>
  26. #include <grpcpp/security/server_credentials.h>
  27. #include <grpcpp/server.h>
  28. #include <grpcpp/server_builder.h>
  29. #include <grpcpp/server_context.h>
  30. #include "src/core/lib/gpr/string.h"
  31. #include "src/proto/grpc/testing/empty.pb.h"
  32. #include "src/proto/grpc/testing/messages.pb.h"
  33. #include "src/proto/grpc/testing/test.grpc.pb.h"
  34. #include "test/cpp/interop/server_helper.h"
  35. #include "test/cpp/util/test_config.h"
  36. ABSL_FLAG(bool, use_alts, false,
  37. "Whether to use alts. Enable alts will disable tls.");
  38. ABSL_FLAG(bool, use_tls, false, "Whether to use tls.");
  39. ABSL_FLAG(std::string, custom_credentials_type, "",
  40. "User provided credentials type.");
  41. ABSL_FLAG(int32_t, port, 0, "Server port.");
  42. ABSL_FLAG(int32_t, max_send_message_size, -1, "The maximum send message size.");
  43. using grpc::Server;
  44. using grpc::ServerBuilder;
  45. using grpc::ServerContext;
  46. using grpc::ServerCredentials;
  47. using grpc::ServerReader;
  48. using grpc::ServerReaderWriter;
  49. using grpc::ServerWriter;
  50. using grpc::Status;
  51. using grpc::WriteOptions;
  52. using grpc::testing::InteropServerContextInspector;
  53. using grpc::testing::Payload;
  54. using grpc::testing::SimpleRequest;
  55. using grpc::testing::SimpleResponse;
  56. using grpc::testing::StreamingInputCallRequest;
  57. using grpc::testing::StreamingInputCallResponse;
  58. using grpc::testing::StreamingOutputCallRequest;
  59. using grpc::testing::StreamingOutputCallResponse;
  60. using grpc::testing::TestService;
  61. const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial";
  62. const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin";
  63. const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent";
  64. void MaybeEchoMetadata(ServerContext* context) {
  65. const auto& client_metadata = context->client_metadata();
  66. GPR_ASSERT(client_metadata.count(kEchoInitialMetadataKey) <= 1);
  67. GPR_ASSERT(client_metadata.count(kEchoTrailingBinMetadataKey) <= 1);
  68. auto iter = client_metadata.find(kEchoInitialMetadataKey);
  69. if (iter != client_metadata.end()) {
  70. context->AddInitialMetadata(
  71. kEchoInitialMetadataKey,
  72. std::string(iter->second.begin(), iter->second.end()));
  73. }
  74. iter = client_metadata.find(kEchoTrailingBinMetadataKey);
  75. if (iter != client_metadata.end()) {
  76. context->AddTrailingMetadata(
  77. kEchoTrailingBinMetadataKey,
  78. std::string(iter->second.begin(), iter->second.end()));
  79. }
  80. // Check if client sent a magic key in the header that makes us echo
  81. // back the user-agent (for testing purpose)
  82. iter = client_metadata.find(kEchoUserAgentKey);
  83. if (iter != client_metadata.end()) {
  84. iter = client_metadata.find("user-agent");
  85. if (iter != client_metadata.end()) {
  86. context->AddInitialMetadata(
  87. kEchoUserAgentKey,
  88. std::string(iter->second.begin(), iter->second.end()));
  89. }
  90. }
  91. }
  92. bool SetPayload(int size, Payload* payload) {
  93. std::unique_ptr<char[]> body(new char[size]());
  94. payload->set_body(body.get(), size);
  95. return true;
  96. }
  97. bool CheckExpectedCompression(const ServerContext& context,
  98. const bool compression_expected) {
  99. const InteropServerContextInspector inspector(context);
  100. const grpc_compression_algorithm received_compression =
  101. inspector.GetCallCompressionAlgorithm();
  102. if (compression_expected) {
  103. if (received_compression == GRPC_COMPRESS_NONE) {
  104. // Expected some compression, got NONE. This is an error.
  105. gpr_log(GPR_ERROR,
  106. "Expected compression but got uncompressed request from client.");
  107. return false;
  108. }
  109. if (!(inspector.WasCompressed())) {
  110. gpr_log(GPR_ERROR,
  111. "Failure: Requested compression in a compressable request, but "
  112. "compression bit in message flags not set.");
  113. return false;
  114. }
  115. } else {
  116. // Didn't expect compression -> make sure the request is uncompressed
  117. if (inspector.WasCompressed()) {
  118. gpr_log(GPR_ERROR,
  119. "Failure: Didn't requested compression, but compression bit in "
  120. "message flags set.");
  121. return false;
  122. }
  123. }
  124. return true;
  125. }
  126. class TestServiceImpl : public TestService::Service {
  127. public:
  128. Status EmptyCall(ServerContext* context,
  129. const grpc::testing::Empty* /*request*/,
  130. grpc::testing::Empty* /*response*/) override {
  131. MaybeEchoMetadata(context);
  132. return Status::OK;
  133. }
  134. // Response contains current timestamp. We ignore everything in the request.
  135. Status CacheableUnaryCall(ServerContext* context,
  136. const SimpleRequest* /*request*/,
  137. SimpleResponse* response) override {
  138. gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE);
  139. std::string timestamp = std::to_string(ts.tv_nsec);
  140. response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size());
  141. context->AddInitialMetadata("cache-control", "max-age=60, public");
  142. return Status::OK;
  143. }
  144. Status UnaryCall(ServerContext* context, const SimpleRequest* request,
  145. SimpleResponse* response) override {
  146. MaybeEchoMetadata(context);
  147. if (request->has_response_compressed()) {
  148. const bool compression_requested = request->response_compressed().value();
  149. gpr_log(GPR_DEBUG, "Request for compression (%s) present for %s",
  150. compression_requested ? "enabled" : "disabled", __func__);
  151. if (compression_requested) {
  152. // Any level would do, let's go for HIGH because we are overachievers.
  153. context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
  154. } else {
  155. context->set_compression_level(GRPC_COMPRESS_LEVEL_NONE);
  156. }
  157. }
  158. if (!CheckExpectedCompression(*context,
  159. request->expect_compressed().value())) {
  160. return Status(grpc::StatusCode::INVALID_ARGUMENT,
  161. "Compressed request expectation not met.");
  162. }
  163. if (request->response_size() > 0) {
  164. if (!SetPayload(request->response_size(), response->mutable_payload())) {
  165. return Status(grpc::StatusCode::INVALID_ARGUMENT,
  166. "Error creating payload.");
  167. }
  168. }
  169. if (request->has_response_status()) {
  170. return Status(
  171. static_cast<grpc::StatusCode>(request->response_status().code()),
  172. request->response_status().message());
  173. }
  174. return Status::OK;
  175. }
  176. Status StreamingOutputCall(
  177. ServerContext* context, const StreamingOutputCallRequest* request,
  178. ServerWriter<StreamingOutputCallResponse>* writer) override {
  179. StreamingOutputCallResponse response;
  180. bool write_success = true;
  181. for (int i = 0; write_success && i < request->response_parameters_size();
  182. i++) {
  183. if (!SetPayload(request->response_parameters(i).size(),
  184. response.mutable_payload())) {
  185. return Status(grpc::StatusCode::INVALID_ARGUMENT,
  186. "Error creating payload.");
  187. }
  188. WriteOptions wopts;
  189. if (request->response_parameters(i).has_compressed()) {
  190. // Compress by default. Disabled on a per-message basis.
  191. context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
  192. const bool compression_requested =
  193. request->response_parameters(i).compressed().value();
  194. gpr_log(GPR_DEBUG, "Request for compression (%s) present for %s",
  195. compression_requested ? "enabled" : "disabled", __func__);
  196. if (!compression_requested) {
  197. wopts.set_no_compression();
  198. } // else, compression is already enabled via the context.
  199. }
  200. int time_us;
  201. if ((time_us = request->response_parameters(i).interval_us()) > 0) {
  202. // Sleep before response if needed
  203. gpr_timespec sleep_time =
  204. gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
  205. gpr_time_from_micros(time_us, GPR_TIMESPAN));
  206. gpr_sleep_until(sleep_time);
  207. }
  208. write_success = writer->Write(response, wopts);
  209. }
  210. if (write_success) {
  211. return Status::OK;
  212. } else {
  213. return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
  214. }
  215. }
  216. Status StreamingInputCall(ServerContext* context,
  217. ServerReader<StreamingInputCallRequest>* reader,
  218. StreamingInputCallResponse* response) override {
  219. StreamingInputCallRequest request;
  220. int aggregated_payload_size = 0;
  221. while (reader->Read(&request)) {
  222. if (!CheckExpectedCompression(*context,
  223. request.expect_compressed().value())) {
  224. return Status(grpc::StatusCode::INVALID_ARGUMENT,
  225. "Compressed request expectation not met.");
  226. }
  227. if (request.has_payload()) {
  228. aggregated_payload_size += request.payload().body().size();
  229. }
  230. }
  231. response->set_aggregated_payload_size(aggregated_payload_size);
  232. return Status::OK;
  233. }
  234. Status FullDuplexCall(
  235. ServerContext* context,
  236. ServerReaderWriter<StreamingOutputCallResponse,
  237. StreamingOutputCallRequest>* stream) override {
  238. MaybeEchoMetadata(context);
  239. StreamingOutputCallRequest request;
  240. StreamingOutputCallResponse response;
  241. bool write_success = true;
  242. while (write_success && stream->Read(&request)) {
  243. if (request.has_response_status()) {
  244. return Status(
  245. static_cast<grpc::StatusCode>(request.response_status().code()),
  246. request.response_status().message());
  247. }
  248. if (request.response_parameters_size() != 0) {
  249. response.mutable_payload()->set_type(request.payload().type());
  250. response.mutable_payload()->set_body(
  251. std::string(request.response_parameters(0).size(), '\0'));
  252. int time_us;
  253. if ((time_us = request.response_parameters(0).interval_us()) > 0) {
  254. // Sleep before response if needed
  255. gpr_timespec sleep_time =
  256. gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
  257. gpr_time_from_micros(time_us, GPR_TIMESPAN));
  258. gpr_sleep_until(sleep_time);
  259. }
  260. write_success = stream->Write(response);
  261. }
  262. }
  263. if (write_success) {
  264. return Status::OK;
  265. } else {
  266. return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
  267. }
  268. }
  269. Status HalfDuplexCall(
  270. ServerContext* /*context*/,
  271. ServerReaderWriter<StreamingOutputCallResponse,
  272. StreamingOutputCallRequest>* stream) override {
  273. std::vector<StreamingOutputCallRequest> requests;
  274. StreamingOutputCallRequest request;
  275. while (stream->Read(&request)) {
  276. requests.push_back(request);
  277. }
  278. StreamingOutputCallResponse response;
  279. bool write_success = true;
  280. for (unsigned int i = 0; write_success && i < requests.size(); i++) {
  281. response.mutable_payload()->set_type(requests[i].payload().type());
  282. if (requests[i].response_parameters_size() == 0) {
  283. return Status(grpc::StatusCode::INTERNAL,
  284. "Request does not have response parameters.");
  285. }
  286. response.mutable_payload()->set_body(
  287. std::string(requests[i].response_parameters(0).size(), '\0'));
  288. write_success = stream->Write(response);
  289. }
  290. if (write_success) {
  291. return Status::OK;
  292. } else {
  293. return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
  294. }
  295. }
  296. };
  297. void grpc::testing::interop::RunServer(
  298. const std::shared_ptr<ServerCredentials>& creds) {
  299. RunServer(creds, absl::GetFlag(FLAGS_port), nullptr, nullptr);
  300. }
  301. void grpc::testing::interop::RunServer(
  302. const std::shared_ptr<ServerCredentials>& creds,
  303. std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
  304. server_options) {
  305. RunServer(creds, absl::GetFlag(FLAGS_port), nullptr,
  306. std::move(server_options));
  307. }
  308. void grpc::testing::interop::RunServer(
  309. const std::shared_ptr<ServerCredentials>& creds, const int port,
  310. ServerStartedCondition* server_started_condition) {
  311. RunServer(creds, port, server_started_condition, nullptr);
  312. }
  313. void grpc::testing::interop::RunServer(
  314. const std::shared_ptr<ServerCredentials>& creds, const int port,
  315. ServerStartedCondition* server_started_condition,
  316. std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
  317. server_options) {
  318. GPR_ASSERT(port != 0);
  319. std::ostringstream server_address;
  320. server_address << "0.0.0.0:" << port;
  321. TestServiceImpl service;
  322. SimpleRequest request;
  323. SimpleResponse response;
  324. ServerBuilder builder;
  325. builder.RegisterService(&service);
  326. builder.AddListeningPort(server_address.str(), creds);
  327. if (server_options != nullptr) {
  328. for (size_t i = 0; i < server_options->size(); i++) {
  329. builder.SetOption(std::move((*server_options)[i]));
  330. }
  331. }
  332. if (absl::GetFlag(FLAGS_max_send_message_size) >= 0) {
  333. builder.SetMaxSendMessageSize(absl::GetFlag(FLAGS_max_send_message_size));
  334. }
  335. std::unique_ptr<Server> server(builder.BuildAndStart());
  336. gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
  337. // Signal that the server has started.
  338. if (server_started_condition) {
  339. std::unique_lock<std::mutex> lock(server_started_condition->mutex);
  340. server_started_condition->server_started = true;
  341. server_started_condition->condition.notify_all();
  342. }
  343. while (!gpr_atm_no_barrier_load(&g_got_sigint)) {
  344. gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
  345. gpr_time_from_seconds(5, GPR_TIMESPAN)));
  346. }
  347. }