Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / deps / grpc / src / core / ext / filters / client_channel / lb_policy / grpclb / load_balancer_api.cc
1 /*
2  *
3  * Copyright 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
19 #include <grpc/support/port_platform.h>
20
21 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
22 #include "src/core/lib/gpr/useful.h"
23
24 #include "google/protobuf/duration.upb.h"
25 #include "google/protobuf/timestamp.upb.h"
26
27 #include <grpc/support/alloc.h>
28
29 namespace grpc_core {
30
31 grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name,
32                                                 upb_arena* arena) {
33   grpc_grpclb_request* req = grpc_lb_v1_LoadBalanceRequest_new(arena);
34   grpc_lb_v1_InitialLoadBalanceRequest* initial_request =
35       grpc_lb_v1_LoadBalanceRequest_mutable_initial_request(req, arena);
36   size_t name_len =
37       GPR_MIN(strlen(lb_service_name), GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
38   grpc_lb_v1_InitialLoadBalanceRequest_set_name(
39       initial_request, upb_strview_make(lb_service_name, name_len));
40   return req;
41 }
42
43 namespace {
44
45 void google_protobuf_Timestamp_assign(google_protobuf_Timestamp* timestamp,
46                                       const gpr_timespec& value) {
47   google_protobuf_Timestamp_set_seconds(timestamp, value.tv_sec);
48   google_protobuf_Timestamp_set_nanos(timestamp, value.tv_nsec);
49 }
50
51 }  // namespace
52
53 grpc_grpclb_request* grpc_grpclb_load_report_request_create(
54     GrpcLbClientStats* client_stats, upb_arena* arena) {
55   grpc_grpclb_request* req = grpc_lb_v1_LoadBalanceRequest_new(arena);
56   grpc_lb_v1_ClientStats* req_stats =
57       grpc_lb_v1_LoadBalanceRequest_mutable_client_stats(req, arena);
58   google_protobuf_Timestamp_assign(
59       grpc_lb_v1_ClientStats_mutable_timestamp(req_stats, arena),
60       gpr_now(GPR_CLOCK_REALTIME));
61
62   int64_t num_calls_started;
63   int64_t num_calls_finished;
64   int64_t num_calls_finished_with_client_failed_to_send;
65   int64_t num_calls_finished_known_received;
66   UniquePtr<GrpcLbClientStats::DroppedCallCounts> drop_token_counts;
67   client_stats->Get(&num_calls_started, &num_calls_finished,
68                     &num_calls_finished_with_client_failed_to_send,
69                     &num_calls_finished_known_received, &drop_token_counts);
70   grpc_lb_v1_ClientStats_set_num_calls_started(req_stats, num_calls_started);
71   grpc_lb_v1_ClientStats_set_num_calls_finished(req_stats, num_calls_finished);
72   grpc_lb_v1_ClientStats_set_num_calls_finished_with_client_failed_to_send(
73       req_stats, num_calls_finished_with_client_failed_to_send);
74   grpc_lb_v1_ClientStats_set_num_calls_finished_known_received(
75       req_stats, num_calls_finished_known_received);
76   if (drop_token_counts != nullptr) {
77     for (size_t i = 0; i < drop_token_counts->size(); ++i) {
78       GrpcLbClientStats::DropTokenCount& cur = (*drop_token_counts)[i];
79       grpc_lb_v1_ClientStatsPerToken* cur_msg =
80           grpc_lb_v1_ClientStats_add_calls_finished_with_drop(req_stats, arena);
81
82       const size_t token_len = strlen(cur.token.get());
83       char* token = reinterpret_cast<char*>(upb_arena_malloc(arena, token_len));
84       memcpy(token, cur.token.get(), token_len);
85
86       grpc_lb_v1_ClientStatsPerToken_set_load_balance_token(
87           cur_msg, upb_strview_make(token, token_len));
88       grpc_lb_v1_ClientStatsPerToken_set_num_calls(cur_msg, cur.count);
89     }
90   }
91   return req;
92 }
93
94 grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request* request,
95                                       upb_arena* arena) {
96   size_t buf_length;
97   char* buf =
98       grpc_lb_v1_LoadBalanceRequest_serialize(request, arena, &buf_length);
99   return grpc_slice_from_copied_buffer(buf, buf_length);
100 }
101
102 const grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse(
103     const grpc_slice& encoded_grpc_grpclb_response, upb_arena* arena) {
104   grpc_lb_v1_LoadBalanceResponse* response =
105       grpc_lb_v1_LoadBalanceResponse_parse(
106           reinterpret_cast<const char*>(
107               GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)),
108           GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response), arena);
109   if (response == nullptr) {
110     gpr_log(GPR_ERROR, "grpc_lb_v1_LoadBalanceResponse parse error");
111     return nullptr;
112   }
113   return grpc_lb_v1_LoadBalanceResponse_initial_response(response);
114 }
115
116 grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist(
117     const grpc_slice& encoded_grpc_grpclb_response) {
118   upb::Arena arena;
119   grpc_lb_v1_LoadBalanceResponse* response =
120       grpc_lb_v1_LoadBalanceResponse_parse(
121           reinterpret_cast<const char*>(
122               GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)),
123           GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response), arena.ptr());
124   if (response == nullptr) {
125     gpr_log(GPR_ERROR, "grpc_lb_v1_LoadBalanceResponse parse error");
126     return nullptr;
127   }
128   grpc_grpclb_serverlist* server_list = static_cast<grpc_grpclb_serverlist*>(
129       gpr_zalloc(sizeof(grpc_grpclb_serverlist)));
130   // First pass: count number of servers.
131   const grpc_lb_v1_ServerList* server_list_msg =
132       grpc_lb_v1_LoadBalanceResponse_server_list(response);
133   size_t server_count = 0;
134   const grpc_lb_v1_Server* const* servers = nullptr;
135   if (server_list_msg != nullptr) {
136     servers = grpc_lb_v1_ServerList_servers(server_list_msg, &server_count);
137   }
138   // Second pass: populate servers.
139   if (server_count > 0) {
140     server_list->servers = static_cast<grpc_grpclb_server**>(
141         gpr_zalloc(sizeof(grpc_grpclb_server*) * server_count));
142     server_list->num_servers = server_count;
143     for (size_t i = 0; i < server_count; ++i) {
144       grpc_grpclb_server* cur = server_list->servers[i] =
145           static_cast<grpc_grpclb_server*>(
146               gpr_zalloc(sizeof(grpc_grpclb_server)));
147       upb_strview address = grpc_lb_v1_Server_ip_address(servers[i]);
148       if (address.size == 0) {
149         ;  // Nothing to do because cur->ip_address is an empty string.
150       } else if (address.size <= GRPC_GRPCLB_SERVER_IP_ADDRESS_MAX_SIZE) {
151         cur->ip_address.size = static_cast<int32_t>(address.size);
152         memcpy(cur->ip_address.data, address.data, address.size);
153       }
154       cur->port = grpc_lb_v1_Server_port(servers[i]);
155       upb_strview token = grpc_lb_v1_Server_load_balance_token(servers[i]);
156       if (token.size == 0) {
157         ;  // Nothing to do because cur->load_balance_token is an empty string.
158       } else if (token.size <= GRPC_GRPCLB_SERVER_LOAD_BALANCE_TOKEN_MAX_SIZE) {
159         memcpy(cur->load_balance_token, token.data, token.size);
160       } else {
161         gpr_log(GPR_ERROR,
162                 "grpc_lb_v1_LoadBalanceResponse has too long token. len=%zu",
163                 token.size);
164       }
165       cur->drop = grpc_lb_v1_Server_drop(servers[i]);
166     }
167   }
168   return server_list;
169 }
170
171 void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist* serverlist) {
172   if (serverlist == nullptr) {
173     return;
174   }
175   for (size_t i = 0; i < serverlist->num_servers; i++) {
176     gpr_free(serverlist->servers[i]);
177   }
178   gpr_free(serverlist->servers);
179   gpr_free(serverlist);
180 }
181
182 grpc_grpclb_serverlist* grpc_grpclb_serverlist_copy(
183     const grpc_grpclb_serverlist* server_list) {
184   grpc_grpclb_serverlist* copy = static_cast<grpc_grpclb_serverlist*>(
185       gpr_zalloc(sizeof(grpc_grpclb_serverlist)));
186   copy->num_servers = server_list->num_servers;
187   copy->servers = static_cast<grpc_grpclb_server**>(
188       gpr_malloc(sizeof(grpc_grpclb_server*) * server_list->num_servers));
189   for (size_t i = 0; i < server_list->num_servers; i++) {
190     copy->servers[i] = static_cast<grpc_grpclb_server*>(
191         gpr_malloc(sizeof(grpc_grpclb_server)));
192     memcpy(copy->servers[i], server_list->servers[i],
193            sizeof(grpc_grpclb_server));
194   }
195   return copy;
196 }
197
198 bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist* lhs,
199                                    const grpc_grpclb_serverlist* rhs) {
200   if (lhs == nullptr || rhs == nullptr) {
201     return false;
202   }
203   if (lhs->num_servers != rhs->num_servers) {
204     return false;
205   }
206   for (size_t i = 0; i < lhs->num_servers; i++) {
207     if (!grpc_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
208       return false;
209     }
210   }
211   return true;
212 }
213
214 bool grpc_grpclb_server_equals(const grpc_grpclb_server* lhs,
215                                const grpc_grpclb_server* rhs) {
216   return memcmp(lhs, rhs, sizeof(grpc_grpclb_server)) == 0;
217 }
218
219 grpc_millis grpc_grpclb_duration_to_millis(
220     const grpc_grpclb_duration* duration_pb) {
221   return static_cast<grpc_millis>(
222       google_protobuf_Duration_seconds(duration_pb) * GPR_MS_PER_SEC +
223       google_protobuf_Duration_nanos(duration_pb) / GPR_NS_PER_MS);
224 }
225
226 }  // namespace grpc_core