1 /*
2 *
3 * Copyright 2018 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
19 #include "test/cpp/end2end/test_health_check_service_impl.h"
20
21 #include <grpc/grpc.h>
22
23 using grpc::health::v1::HealthCheckRequest;
24 using grpc::health::v1::HealthCheckResponse;
25
26 namespace grpc {
27 namespace testing {
28
Check(ServerContext *,const HealthCheckRequest * request,HealthCheckResponse * response)29 Status HealthCheckServiceImpl::Check(ServerContext* /*context*/,
30 const HealthCheckRequest* request,
31 HealthCheckResponse* response) {
32 std::lock_guard<std::mutex> lock(mu_);
33 auto iter = status_map_.find(request->service());
34 if (iter == status_map_.end()) {
35 return Status(StatusCode::NOT_FOUND, "");
36 }
37 response->set_status(iter->second);
38 return Status::OK;
39 }
40
Watch(ServerContext * context,const HealthCheckRequest * request,::grpc::ServerWriter<HealthCheckResponse> * writer)41 Status HealthCheckServiceImpl::Watch(
42 ServerContext* context, const HealthCheckRequest* request,
43 ::grpc::ServerWriter<HealthCheckResponse>* writer) {
44 auto last_state = HealthCheckResponse::UNKNOWN;
45 while (!context->IsCancelled()) {
46 {
47 std::lock_guard<std::mutex> lock(mu_);
48 HealthCheckResponse response;
49 auto iter = status_map_.find(request->service());
50 if (iter == status_map_.end()) {
51 response.set_status(response.SERVICE_UNKNOWN);
52 } else {
53 response.set_status(iter->second);
54 }
55 if (response.status() != last_state) {
56 writer->Write(response, ::grpc::WriteOptions());
57 last_state = response.status();
58 }
59 }
60 gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
61 gpr_time_from_millis(1000, GPR_TIMESPAN)));
62 }
63 return Status::OK;
64 }
65
SetStatus(const std::string & service_name,HealthCheckResponse::ServingStatus status)66 void HealthCheckServiceImpl::SetStatus(
67 const std::string& service_name,
68 HealthCheckResponse::ServingStatus status) {
69 std::lock_guard<std::mutex> lock(mu_);
70 if (shutdown_) {
71 status = HealthCheckResponse::NOT_SERVING;
72 }
73 status_map_[service_name] = status;
74 }
75
SetAll(HealthCheckResponse::ServingStatus status)76 void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) {
77 std::lock_guard<std::mutex> lock(mu_);
78 if (shutdown_) {
79 return;
80 }
81 for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
82 iter->second = status;
83 }
84 }
85
Shutdown()86 void HealthCheckServiceImpl::Shutdown() {
87 std::lock_guard<std::mutex> lock(mu_);
88 if (shutdown_) {
89 return;
90 }
91 shutdown_ = true;
92 for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
93 iter->second = HealthCheckResponse::NOT_SERVING;
94 }
95 }
96
97 } // namespace testing
98 } // namespace grpc
99