Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into libuv_em_basic
Browse files Browse the repository at this point in the history
  • Loading branch information
guantaol committed Dec 5, 2019
2 parents ee4b311 + 866cb72 commit 81b4bc0
Show file tree
Hide file tree
Showing 18 changed files with 526 additions and 170 deletions.
81 changes: 59 additions & 22 deletions src/core/ext/filters/client_channel/xds/xds_bootstrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,23 @@ XdsBootstrap::XdsBootstrap(grpc_slice contents, grpc_error** error)
return;
}
InlinedVector<grpc_error*, 1> error_list;
bool seen_xds_server = false;
bool seen_xds_servers = false;
bool seen_node = false;
for (grpc_json* child = tree_->child; child != nullptr; child = child->next) {
if (child->key == nullptr) {
error_list.push_back(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("JSON key is null"));
} else if (strcmp(child->key, "xds_server") == 0) {
if (child->type != GRPC_JSON_OBJECT) {
} else if (strcmp(child->key, "xds_servers") == 0) {
if (child->type != GRPC_JSON_ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"xds_server\" field is not an object"));
"\"xds_servers\" field is not an array"));
}
if (seen_xds_server) {
if (seen_xds_servers) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"duplicate \"xds_server\" field"));
"duplicate \"xds_servers\" field"));
}
seen_xds_server = true;
grpc_error* parse_error = ParseXdsServer(child);
seen_xds_servers = true;
grpc_error* parse_error = ParseXdsServerList(child);
if (parse_error != GRPC_ERROR_NONE) error_list.push_back(parse_error);
} else if (strcmp(child->key, "node") == 0) {
if (child->type != GRPC_JSON_OBJECT) {
Expand All @@ -90,9 +90,9 @@ XdsBootstrap::XdsBootstrap(grpc_slice contents, grpc_error** error)
if (parse_error != GRPC_ERROR_NONE) error_list.push_back(parse_error);
}
}
if (!seen_xds_server) {
if (!seen_xds_servers) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"xds_server\" field not present"));
"\"xds_servers\" field not present"));
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("errors parsing xds bootstrap file",
&error_list);
Expand All @@ -103,9 +103,33 @@ XdsBootstrap::~XdsBootstrap() {
grpc_slice_unref_internal(contents_);
}

grpc_error* XdsBootstrap::ParseXdsServer(grpc_json* json) {
grpc_error* XdsBootstrap::ParseXdsServerList(grpc_json* json) {
InlinedVector<grpc_error*, 1> error_list;
server_uri_ = nullptr;
size_t idx = 0;
for (grpc_json *child = json->child; child != nullptr;
child = child->next, ++idx) {
if (child->key != nullptr) {
char* msg;
gpr_asprintf(&msg, "array element %" PRIuPTR " key is not null", idx);
error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
}
if (child->type != GRPC_JSON_OBJECT) {
char* msg;
gpr_asprintf(&msg, "array element %" PRIuPTR " is not an object", idx);
error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
} else {
grpc_error* parse_error = ParseXdsServer(child, idx);
if (parse_error != GRPC_ERROR_NONE) error_list.push_back(parse_error);
}
}
return GRPC_ERROR_CREATE_FROM_VECTOR("errors parsing \"xds_servers\" array",
&error_list);
}

grpc_error* XdsBootstrap::ParseXdsServer(grpc_json* json, size_t idx) {
InlinedVector<grpc_error*, 1> error_list;
servers_.emplace_back();
XdsServer& server = servers_[servers_.size() - 1];
bool seen_channel_creds = false;
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
if (child->key == nullptr) {
Expand All @@ -116,11 +140,11 @@ grpc_error* XdsBootstrap::ParseXdsServer(grpc_json* json) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"server_uri\" field is not a string"));
}
if (server_uri_ != nullptr) {
if (server.server_uri != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"duplicate \"server_uri\" field"));
}
server_uri_ = child->value;
server.server_uri = child->value;
} else if (strcmp(child->key, "channel_creds") == 0) {
if (child->type != GRPC_JSON_ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
Expand All @@ -131,19 +155,29 @@ grpc_error* XdsBootstrap::ParseXdsServer(grpc_json* json) {
"duplicate \"channel_creds\" field"));
}
seen_channel_creds = true;
grpc_error* parse_error = ParseChannelCredsArray(child);
grpc_error* parse_error = ParseChannelCredsArray(child, &server);
if (parse_error != GRPC_ERROR_NONE) error_list.push_back(parse_error);
}
}
if (server_uri_ == nullptr) {
if (server.server_uri == nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"server_uri\" field not present"));
}
return GRPC_ERROR_CREATE_FROM_VECTOR("errors parsing \"xds_server\" object",
&error_list);
// Can't use GRPC_ERROR_CREATE_FROM_VECTOR() here, because the error
// string is not static in this case.
if (error_list.empty()) return GRPC_ERROR_NONE;
char* msg;
gpr_asprintf(&msg, "errors parsing index %" PRIuPTR, idx);
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
for (size_t i = 0; i < error_list.size(); ++i) {
error = grpc_error_add_child(error, error_list[i]);
}
return error;
}

grpc_error* XdsBootstrap::ParseChannelCredsArray(grpc_json* json) {
grpc_error* XdsBootstrap::ParseChannelCredsArray(grpc_json* json,
XdsServer* server) {
InlinedVector<grpc_error*, 1> error_list;
size_t idx = 0;
for (grpc_json *child = json->child; child != nullptr;
Expand All @@ -158,15 +192,16 @@ grpc_error* XdsBootstrap::ParseChannelCredsArray(grpc_json* json) {
gpr_asprintf(&msg, "array element %" PRIuPTR " is not an object", idx);
error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
} else {
grpc_error* parse_error = ParseChannelCreds(child, idx);
grpc_error* parse_error = ParseChannelCreds(child, idx, server);
if (parse_error != GRPC_ERROR_NONE) error_list.push_back(parse_error);
}
}
return GRPC_ERROR_CREATE_FROM_VECTOR("errors parsing \"channel_creds\" array",
&error_list);
}

grpc_error* XdsBootstrap::ParseChannelCreds(grpc_json* json, size_t idx) {
grpc_error* XdsBootstrap::ParseChannelCreds(grpc_json* json, size_t idx,
XdsServer* server) {
InlinedVector<grpc_error*, 1> error_list;
ChannelCreds channel_creds;
for (grpc_json* child = json->child; child != nullptr; child = child->next) {
Expand Down Expand Up @@ -195,7 +230,9 @@ grpc_error* XdsBootstrap::ParseChannelCreds(grpc_json* json, size_t idx) {
channel_creds.config = child;
}
}
if (channel_creds.type != nullptr) channel_creds_.push_back(channel_creds);
if (channel_creds.type != nullptr) {
server->channel_creds.push_back(channel_creds);
}
// Can't use GRPC_ERROR_CREATE_FROM_VECTOR() here, because the error
// string is not static in this case.
if (error_list.empty()) return GRPC_ERROR_NONE;
Expand Down
22 changes: 13 additions & 9 deletions src/core/ext/filters/client_channel/xds/xds_bootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class XdsBootstrap {
grpc_json* config = nullptr;
};

struct XdsServer {
const char* server_uri = nullptr;
InlinedVector<ChannelCreds, 1> channel_creds;
};

// If *error is not GRPC_ERROR_NONE after returning, then there was an
// error reading the file.
static std::unique_ptr<XdsBootstrap> ReadFromFile(grpc_error** error);
Expand All @@ -66,16 +71,16 @@ class XdsBootstrap {
XdsBootstrap(grpc_slice contents, grpc_error** error);
~XdsBootstrap();

const char* server_uri() const { return server_uri_; }
const InlinedVector<ChannelCreds, 1>& channel_creds() const {
return channel_creds_;
}
// TODO(roth): We currently support only one server. Fix this when we
// add support for fallback for the xds channel.
const XdsServer& server() const { return servers_[0]; }
const Node* node() const { return node_.get(); }

private:
grpc_error* ParseXdsServer(grpc_json* json);
grpc_error* ParseChannelCredsArray(grpc_json* json);
grpc_error* ParseChannelCreds(grpc_json* json, size_t idx);
grpc_error* ParseXdsServerList(grpc_json* json);
grpc_error* ParseXdsServer(grpc_json* json, size_t idx);
grpc_error* ParseChannelCredsArray(grpc_json* json, XdsServer* server);
grpc_error* ParseChannelCreds(grpc_json* json, size_t idx, XdsServer* server);
grpc_error* ParseNode(grpc_json* json);
grpc_error* ParseLocality(grpc_json* json);

Expand All @@ -90,8 +95,7 @@ class XdsBootstrap {
grpc_slice contents_;
grpc_json* tree_ = nullptr;

const char* server_uri_ = nullptr;
InlinedVector<ChannelCreds, 1> channel_creds_;
InlinedVector<XdsServer, 1> servers_;
std::unique_ptr<Node> node_;
};

Expand Down
5 changes: 3 additions & 2 deletions src/core/ext/filters/client_channel/xds/xds_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ grpc_channel_args* ModifyXdsChannelArgs(grpc_channel_args* args) {

grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
const grpc_channel_args& args) {
if (!bootstrap.channel_creds().empty()) return nullptr;
return grpc_insecure_channel_create(bootstrap.server_uri(), &args, nullptr);
if (!bootstrap.server().channel_creds.empty()) return nullptr;
return grpc_insecure_channel_create(bootstrap.server().server_uri, &args,
nullptr);
}

} // namespace grpc_core
14 changes: 8 additions & 6 deletions src/core/ext/filters/client_channel/xds/xds_channel_secure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
const grpc_channel_args& args) {
grpc_channel_credentials* creds = nullptr;
RefCountedPtr<grpc_channel_credentials> creds_to_unref;
if (!bootstrap.channel_creds().empty()) {
for (size_t i = 0; i < bootstrap.channel_creds().size(); ++i) {
if (strcmp(bootstrap.channel_creds()[i].type, "google_default") == 0) {
if (!bootstrap.server().channel_creds.empty()) {
for (size_t i = 0; i < bootstrap.server().channel_creds.size(); ++i) {
if (strcmp(bootstrap.server().channel_creds[i].type, "google_default") ==
0) {
creds = grpc_google_default_credentials_create();
break;
} else if (strcmp(bootstrap.channel_creds()[i].type, "fake") == 0) {
} else if (strcmp(bootstrap.server().channel_creds[i].type, "fake") ==
0) {
creds = grpc_fake_transport_security_credentials_create();
break;
}
Expand All @@ -83,15 +85,15 @@ grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap,
creds = grpc_channel_credentials_find_in_args(&args);
if (creds == nullptr) {
// Built with security but parent channel is insecure.
return grpc_insecure_channel_create(bootstrap.server_uri(), &args,
return grpc_insecure_channel_create(bootstrap.server().server_uri, &args,
nullptr);
}
}
const char* arg_to_remove = GRPC_ARG_CHANNEL_CREDENTIALS;
grpc_channel_args* new_args =
grpc_channel_args_copy_and_remove(&args, &arg_to_remove, 1);
grpc_channel* channel = grpc_secure_channel_create(
creds, bootstrap.server_uri(), new_args, nullptr);
creds, bootstrap.server().server_uri, new_args, nullptr);
grpc_channel_args_destroy(new_args);
return channel;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/ext/filters/client_channel/xds/xds_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ XdsClient::XdsClient(Combiner* combiner, grpc_pollset_set* interested_parties,
}
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO, "[xds_client %p: creating channel to %s", this,
bootstrap_->server_uri());
bootstrap_->server().server_uri);
}
chand_ = MakeOrphanable<ChannelState>(
Ref(DEBUG_LOCATION, "XdsClient+ChannelState"), channel_args);
Expand Down
98 changes: 98 additions & 0 deletions src/csharp/Grpc.Core.Api/AsyncCallState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#region Copyright notice and license

// Copyright 2019 The 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.

#endregion


using System;
using System.Threading.Tasks;

namespace Grpc.Core
{
/// <summary>
/// Provides an abstraction over the callback providers
/// used by AsyncUnaryCall, AsyncDuplexStreamingCall, etc
/// </summary>
internal struct AsyncCallState
{
readonly object responseHeadersAsync; // Task<Metadata> or Func<object, Task<Metadata>>
readonly object getStatusFunc; // Func<Status> or Func<object, Status>
readonly object getTrailersFunc; // Func<Metadata> or Func<object, Metadata>
readonly object disposeAction; // Action or Action<object>
readonly object callbackState; // arg0 for the callbacks above, if needed

internal AsyncCallState(
Func<object, Task<Metadata>> responseHeadersAsync,
Func<object, Status> getStatusFunc,
Func<object, Metadata> getTrailersFunc,
Action<object> disposeAction,
object callbackState)
{
this.responseHeadersAsync = responseHeadersAsync;
this.getStatusFunc = getStatusFunc;
this.getTrailersFunc = getTrailersFunc;
this.disposeAction = disposeAction;
this.callbackState = callbackState;
}

internal AsyncCallState(
Task<Metadata> responseHeadersAsync,
Func<Status> getStatusFunc,
Func<Metadata> getTrailersFunc,
Action disposeAction)
{
this.responseHeadersAsync = responseHeadersAsync;
this.getStatusFunc = getStatusFunc;
this.getTrailersFunc = getTrailersFunc;
this.disposeAction = disposeAction;
this.callbackState = null;
}

internal Task<Metadata> ResponseHeadersAsync()
{
var withState = responseHeadersAsync as Func<object, Task<Metadata>>;
return withState != null ? withState(callbackState)
: (Task<Metadata>)responseHeadersAsync;
}

internal Status GetStatus()
{
var withState = getStatusFunc as Func<object, Status>;
return withState != null ? withState(callbackState)
: ((Func<Status>)getStatusFunc)();
}

internal Metadata GetTrailers()
{
var withState = getTrailersFunc as Func<object, Metadata>;
return withState != null ? withState(callbackState)
: ((Func<Metadata>)getTrailersFunc)();
}

internal void Dispose()
{
var withState = disposeAction as Action<object>;
if (withState != null)
{
withState(callbackState);
}
else
{
((Action)disposeAction)();
}
}
}
}
Loading

0 comments on commit 81b4bc0

Please sign in to comment.