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
diff --git a/legacy-libs/grpc/deps/grpc/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc b/legacy-libs/grpc/deps/grpc/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
new file mode 100644 (file)
index 0000000..68097e1
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/lib/gpr/useful.h"
+
+#include "google/protobuf/duration.upb.h"
+#include "google/protobuf/timestamp.upb.h"
+
+#include <grpc/support/alloc.h>
+
+namespace grpc_core {
+
+grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name,
+                                                upb_arena* arena) {
+  grpc_grpclb_request* req = grpc_lb_v1_LoadBalanceRequest_new(arena);
+  grpc_lb_v1_InitialLoadBalanceRequest* initial_request =
+      grpc_lb_v1_LoadBalanceRequest_mutable_initial_request(req, arena);
+  size_t name_len =
+      GPR_MIN(strlen(lb_service_name), GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
+  grpc_lb_v1_InitialLoadBalanceRequest_set_name(
+      initial_request, upb_strview_make(lb_service_name, name_len));
+  return req;
+}
+
+namespace {
+
+void google_protobuf_Timestamp_assign(google_protobuf_Timestamp* timestamp,
+                                      const gpr_timespec& value) {
+  google_protobuf_Timestamp_set_seconds(timestamp, value.tv_sec);
+  google_protobuf_Timestamp_set_nanos(timestamp, value.tv_nsec);
+}
+
+}  // namespace
+
+grpc_grpclb_request* grpc_grpclb_load_report_request_create(
+    GrpcLbClientStats* client_stats, upb_arena* arena) {
+  grpc_grpclb_request* req = grpc_lb_v1_LoadBalanceRequest_new(arena);
+  grpc_lb_v1_ClientStats* req_stats =
+      grpc_lb_v1_LoadBalanceRequest_mutable_client_stats(req, arena);
+  google_protobuf_Timestamp_assign(
+      grpc_lb_v1_ClientStats_mutable_timestamp(req_stats, arena),
+      gpr_now(GPR_CLOCK_REALTIME));
+
+  int64_t num_calls_started;
+  int64_t num_calls_finished;
+  int64_t num_calls_finished_with_client_failed_to_send;
+  int64_t num_calls_finished_known_received;
+  UniquePtr<GrpcLbClientStats::DroppedCallCounts> drop_token_counts;
+  client_stats->Get(&num_calls_started, &num_calls_finished,
+                    &num_calls_finished_with_client_failed_to_send,
+                    &num_calls_finished_known_received, &drop_token_counts);
+  grpc_lb_v1_ClientStats_set_num_calls_started(req_stats, num_calls_started);
+  grpc_lb_v1_ClientStats_set_num_calls_finished(req_stats, num_calls_finished);
+  grpc_lb_v1_ClientStats_set_num_calls_finished_with_client_failed_to_send(
+      req_stats, num_calls_finished_with_client_failed_to_send);
+  grpc_lb_v1_ClientStats_set_num_calls_finished_known_received(
+      req_stats, num_calls_finished_known_received);
+  if (drop_token_counts != nullptr) {
+    for (size_t i = 0; i < drop_token_counts->size(); ++i) {
+      GrpcLbClientStats::DropTokenCount& cur = (*drop_token_counts)[i];
+      grpc_lb_v1_ClientStatsPerToken* cur_msg =
+          grpc_lb_v1_ClientStats_add_calls_finished_with_drop(req_stats, arena);
+
+      const size_t token_len = strlen(cur.token.get());
+      char* token = reinterpret_cast<char*>(upb_arena_malloc(arena, token_len));
+      memcpy(token, cur.token.get(), token_len);
+
+      grpc_lb_v1_ClientStatsPerToken_set_load_balance_token(
+          cur_msg, upb_strview_make(token, token_len));
+      grpc_lb_v1_ClientStatsPerToken_set_num_calls(cur_msg, cur.count);
+    }
+  }
+  return req;
+}
+
+grpc_slice grpc_grpclb_request_encode(const grpc_grpclb_request* request,
+                                      upb_arena* arena) {
+  size_t buf_length;
+  char* buf =
+      grpc_lb_v1_LoadBalanceRequest_serialize(request, arena, &buf_length);
+  return grpc_slice_from_copied_buffer(buf, buf_length);
+}
+
+const grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse(
+    const grpc_slice& encoded_grpc_grpclb_response, upb_arena* arena) {
+  grpc_lb_v1_LoadBalanceResponse* response =
+      grpc_lb_v1_LoadBalanceResponse_parse(
+          reinterpret_cast<const char*>(
+              GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)),
+          GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response), arena);
+  if (response == nullptr) {
+    gpr_log(GPR_ERROR, "grpc_lb_v1_LoadBalanceResponse parse error");
+    return nullptr;
+  }
+  return grpc_lb_v1_LoadBalanceResponse_initial_response(response);
+}
+
+grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist(
+    const grpc_slice& encoded_grpc_grpclb_response) {
+  upb::Arena arena;
+  grpc_lb_v1_LoadBalanceResponse* response =
+      grpc_lb_v1_LoadBalanceResponse_parse(
+          reinterpret_cast<const char*>(
+              GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)),
+          GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response), arena.ptr());
+  if (response == nullptr) {
+    gpr_log(GPR_ERROR, "grpc_lb_v1_LoadBalanceResponse parse error");
+    return nullptr;
+  }
+  grpc_grpclb_serverlist* server_list = static_cast<grpc_grpclb_serverlist*>(
+      gpr_zalloc(sizeof(grpc_grpclb_serverlist)));
+  // First pass: count number of servers.
+  const grpc_lb_v1_ServerList* server_list_msg =
+      grpc_lb_v1_LoadBalanceResponse_server_list(response);
+  size_t server_count = 0;
+  const grpc_lb_v1_Server* const* servers = nullptr;
+  if (server_list_msg != nullptr) {
+    servers = grpc_lb_v1_ServerList_servers(server_list_msg, &server_count);
+  }
+  // Second pass: populate servers.
+  if (server_count > 0) {
+    server_list->servers = static_cast<grpc_grpclb_server**>(
+        gpr_zalloc(sizeof(grpc_grpclb_server*) * server_count));
+    server_list->num_servers = server_count;
+    for (size_t i = 0; i < server_count; ++i) {
+      grpc_grpclb_server* cur = server_list->servers[i] =
+          static_cast<grpc_grpclb_server*>(
+              gpr_zalloc(sizeof(grpc_grpclb_server)));
+      upb_strview address = grpc_lb_v1_Server_ip_address(servers[i]);
+      if (address.size == 0) {
+        ;  // Nothing to do because cur->ip_address is an empty string.
+      } else if (address.size <= GRPC_GRPCLB_SERVER_IP_ADDRESS_MAX_SIZE) {
+        cur->ip_address.size = static_cast<int32_t>(address.size);
+        memcpy(cur->ip_address.data, address.data, address.size);
+      }
+      cur->port = grpc_lb_v1_Server_port(servers[i]);
+      upb_strview token = grpc_lb_v1_Server_load_balance_token(servers[i]);
+      if (token.size == 0) {
+        ;  // Nothing to do because cur->load_balance_token is an empty string.
+      } else if (token.size <= GRPC_GRPCLB_SERVER_LOAD_BALANCE_TOKEN_MAX_SIZE) {
+        memcpy(cur->load_balance_token, token.data, token.size);
+      } else {
+        gpr_log(GPR_ERROR,
+                "grpc_lb_v1_LoadBalanceResponse has too long token. len=%zu",
+                token.size);
+      }
+      cur->drop = grpc_lb_v1_Server_drop(servers[i]);
+    }
+  }
+  return server_list;
+}
+
+void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist* serverlist) {
+  if (serverlist == nullptr) {
+    return;
+  }
+  for (size_t i = 0; i < serverlist->num_servers; i++) {
+    gpr_free(serverlist->servers[i]);
+  }
+  gpr_free(serverlist->servers);
+  gpr_free(serverlist);
+}
+
+grpc_grpclb_serverlist* grpc_grpclb_serverlist_copy(
+    const grpc_grpclb_serverlist* server_list) {
+  grpc_grpclb_serverlist* copy = static_cast<grpc_grpclb_serverlist*>(
+      gpr_zalloc(sizeof(grpc_grpclb_serverlist)));
+  copy->num_servers = server_list->num_servers;
+  copy->servers = static_cast<grpc_grpclb_server**>(
+      gpr_malloc(sizeof(grpc_grpclb_server*) * server_list->num_servers));
+  for (size_t i = 0; i < server_list->num_servers; i++) {
+    copy->servers[i] = static_cast<grpc_grpclb_server*>(
+        gpr_malloc(sizeof(grpc_grpclb_server)));
+    memcpy(copy->servers[i], server_list->servers[i],
+           sizeof(grpc_grpclb_server));
+  }
+  return copy;
+}
+
+bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist* lhs,
+                                   const grpc_grpclb_serverlist* rhs) {
+  if (lhs == nullptr || rhs == nullptr) {
+    return false;
+  }
+  if (lhs->num_servers != rhs->num_servers) {
+    return false;
+  }
+  for (size_t i = 0; i < lhs->num_servers; i++) {
+    if (!grpc_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool grpc_grpclb_server_equals(const grpc_grpclb_server* lhs,
+                               const grpc_grpclb_server* rhs) {
+  return memcmp(lhs, rhs, sizeof(grpc_grpclb_server)) == 0;
+}
+
+grpc_millis grpc_grpclb_duration_to_millis(
+    const grpc_grpclb_duration* duration_pb) {
+  return static_cast<grpc_millis>(
+      google_protobuf_Duration_seconds(duration_pb) * GPR_MS_PER_SEC +
+      google_protobuf_Duration_nanos(duration_pb) / GPR_NS_PER_MS);
+}
+
+}  // namespace grpc_core