Merge branch 'master' into grpc_namespace_server

pull/18458/head
Karthik Ravi Shankar 6 years ago
commit c50dd23ea7
  1. 3
      BUILD
  2. 2
      BUILD.gn
  3. 7
      CMakeLists.txt
  4. 7
      Makefile
  5. 40
      WORKSPACE
  6. 16
      bazel/grpc_python_deps.bzl
  7. 3
      build.yaml
  8. 4
      doc/PROTOCOL-HTTP2.md
  9. 2
      gRPC-C++.podspec
  10. 2
      grpc.gemspec
  11. 34
      include/grpcpp/ext/proto_server_reflection_plugin.h
  12. 55
      include/grpcpp/ext/proto_server_reflection_plugin_impl.h
  13. 78
      include/grpcpp/generic/generic_stub.h
  14. 108
      include/grpcpp/generic/generic_stub_impl.h
  15. 7
      include/grpcpp/impl/codegen/server_interface.h
  16. 65
      include/grpcpp/security/server_credentials.h
  17. 85
      include/grpcpp/security/server_credentials_impl.h
  18. 14
      include/grpcpp/server_builder.h
  19. 222
      src/core/ext/filters/client_channel/client_channel.cc
  20. 24
      src/core/ext/filters/client_channel/health/health_check_client.cc
  21. 12
      src/core/ext/filters/client_channel/health/health_check_client.h
  22. 7
      src/core/ext/filters/client_channel/lb_policy.cc
  23. 15
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  24. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
  25. 20
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
  26. 4
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
  27. 2
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
  28. 1
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  29. 82
      src/cpp/client/generic_stub.cc
  30. 4
      src/cpp/ext/proto_server_reflection_plugin.cc
  31. 6
      src/cpp/server/insecure_server_credentials.cc
  32. 16
      src/cpp/server/secure_server_credentials.cc
  33. 17
      src/cpp/server/secure_server_credentials.h
  34. 6
      src/cpp/server/server_credentials.cc
  35. 2
      templates/grpc.gemspec.template
  36. 2
      test/cpp/end2end/cfstream_test.cc
  37. 1
      test/cpp/util/test_credentials_provider.cc
  38. 2
      tools/doxygen/Doxyfile.c++
  39. 2
      tools/doxygen/Doxyfile.c++.internal
  40. 2
      tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
  41. 369
      tools/release/release_notes.py
  42. 6
      tools/run_tests/generated/sources_and_headers.json

@ -225,6 +225,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/generic/generic_stub_impl.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
@ -252,6 +253,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
"include/grpcpp/server_impl.h",
"include/grpcpp/server_builder.h",
@ -2198,6 +2200,7 @@ grpc_cc_library(
public_hdrs = [
"include/grpc++/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin_impl.h",
],
deps = [
":grpc++",

@ -1012,6 +1012,7 @@ config("grpc_config") {
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/generic/generic_stub_impl.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
@ -1083,6 +1084,7 @@ config("grpc_config") {
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
"include/grpcpp/server_context.h",

@ -3006,6 +3006,7 @@ foreach(_hdr
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/generic/generic_stub_impl.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
@ -3031,6 +3032,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/server_context.h
@ -3605,6 +3607,7 @@ foreach(_hdr
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/generic/generic_stub_impl.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
@ -3630,6 +3633,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/server_context.h
@ -3976,6 +3980,7 @@ target_link_libraries(grpc++_reflection
foreach(_hdr
include/grpc++/ext/proto_server_reflection_plugin.h
include/grpcpp/ext/proto_server_reflection_plugin.h
include/grpcpp/ext/proto_server_reflection_plugin_impl.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@ -4577,6 +4582,7 @@ foreach(_hdr
include/grpcpp/ext/health_check_service_server_builder_option.h
include/grpcpp/generic/async_generic_service.h
include/grpcpp/generic/generic_stub.h
include/grpcpp/generic/generic_stub_impl.h
include/grpcpp/grpcpp.h
include/grpcpp/health_check_service_interface.h
include/grpcpp/health_check_service_interface_impl.h
@ -4602,6 +4608,7 @@ foreach(_hdr
include/grpcpp/security/auth_metadata_processor_impl.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/server_credentials_impl.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/server_context.h

@ -5337,6 +5337,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/generic/generic_stub_impl.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
@ -5362,6 +5363,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \
@ -5944,6 +5946,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/generic/generic_stub_impl.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
@ -5969,6 +5972,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \
@ -6314,6 +6318,7 @@ LIBGRPC++_REFLECTION_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/ext/proto_server_reflection_plugin.h \
include/grpcpp/ext/proto_server_reflection_plugin.h \
include/grpcpp/ext/proto_server_reflection_plugin_impl.h \
LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
@ -6865,6 +6870,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/generic/generic_stub_impl.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
@ -6890,6 +6896,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \

@ -17,20 +17,13 @@ register_toolchains(
"//third_party/toolchains:cc-toolchain-clang-x86_64-default",
)
http_archive(
name = "cython",
build_file = "//third_party:cython.BUILD",
sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
urls = [
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz",
],
# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency.
git_repository(
name = "org_pubref_rules_protobuf",
remote = "https://github.com/ghostwriternr/rules_protobuf",
tag = "v0.8.2.1-alpha",
)
load("//third_party/py:python_configure.bzl", "python_configure")
python_configure(name = "local_config_python")
git_repository(
name = "io_bazel_rules_python",
commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
@ -39,24 +32,21 @@ git_repository(
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import")
pip_repositories()
pip_import(
name = "grpc_python_dependencies",
requirements = "//:requirements.bazel.txt",
)
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
pip_install()
# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged.
git_repository(
name = "org_pubref_rules_protobuf",
remote = "https://github.com/ghostwriternr/rules_protobuf",
tag = "v0.8.2.1-alpha",
http_archive(
name = "cython",
build_file = "//third_party:cython.BUILD",
sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
urls = [
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz",
],
)
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
load("//bazel:grpc_python_deps.bzl", "grpc_python_deps")
py_proto_repositories()
grpc_python_deps()

@ -0,0 +1,16 @@
load("//third_party/py:python_configure.bzl", "python_configure")
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories")
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
def grpc_python_deps():
# TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional.
if hasattr(native, "http_archive"):
python_configure(name = "local_config_python")
pip_repositories()
pip_install()
py_proto_repositories()
else:
print("Building Python gRPC with bazel 23.0+ is disabled pending " +
"resolution of https://github.com/grpc/grpc/issues/18256.")

@ -1352,6 +1352,7 @@ filegroups:
- include/grpcpp/ext/health_check_service_server_builder_option.h
- include/grpcpp/generic/async_generic_service.h
- include/grpcpp/generic/generic_stub.h
- include/grpcpp/generic/generic_stub_impl.h
- include/grpcpp/grpcpp.h
- include/grpcpp/health_check_service_interface.h
- include/grpcpp/health_check_service_interface_impl.h
@ -1377,6 +1378,7 @@ filegroups:
- include/grpcpp/security/auth_metadata_processor_impl.h
- include/grpcpp/security/credentials.h
- include/grpcpp/security/server_credentials.h
- include/grpcpp/security/server_credentials_impl.h
- include/grpcpp/server.h
- include/grpcpp/server_builder.h
- include/grpcpp/server_context.h
@ -1750,6 +1752,7 @@ libs:
public_headers:
- include/grpc++/ext/proto_server_reflection_plugin.h
- include/grpcpp/ext/proto_server_reflection_plugin.h
- include/grpcpp/ext/proto_server_reflection_plugin_impl.h
headers:
- src/cpp/ext/proto_server_reflection.h
src:

@ -61,6 +61,8 @@ the form shown above.
If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements.
If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 415 (Unsupported Media Type). This will prevent other HTTP/2 clients from interpreting a gRPC error response, which uses status 200 (OK), as successful.
**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**.
Note that HTTP2 does not allow arbitrary octet sequences for header values so binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. Applications define binary headers by having their names end with "-bin". Runtime libraries use this suffix to detect binary headers and properly apply base64 encoding & decoding as headers are sent and received.
@ -255,5 +257,3 @@ to be used.
* **Service-Name** → ?( {_proto package name_} "." ) {_service name_}
* **Message-Type** → {_fully qualified proto message name_}
* **Content-Type** → "application/grpc+proto"

@ -91,6 +91,7 @@ Pod::Spec.new do |s|
'include/grpcpp/ext/health_check_service_server_builder_option.h',
'include/grpcpp/generic/async_generic_service.h',
'include/grpcpp/generic/generic_stub.h',
'include/grpcpp/generic/generic_stub_impl.h',
'include/grpcpp/grpcpp.h',
'include/grpcpp/health_check_service_interface.h',
'include/grpcpp/health_check_service_interface_impl.h',
@ -116,6 +117,7 @@ Pod::Spec.new do |s|
'include/grpcpp/security/auth_metadata_processor_impl.h',
'include/grpcpp/security/credentials.h',
'include/grpcpp/security/server_credentials.h',
'include/grpcpp/security/server_credentials_impl.h',
'include/grpcpp/server.h',
'include/grpcpp/server_builder.h',
'include/grpcpp/server_context.h',

@ -30,7 +30,7 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.7'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'facter', '~> 2.4'

@ -1,6 +1,6 @@
/*
*
* Copyright 2015 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,37 +19,17 @@
#ifndef GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
#define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/support/config.h>
namespace grpc_impl {
class ServerInitializer;
}
namespace grpc {
class ProtoServerReflection;
} // namespace grpc
#include <grpcpp/ext/proto_server_reflection_plugin_impl.h>
namespace grpc {
namespace reflection {
class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
public:
ProtoServerReflectionPlugin();
::grpc::string name() override;
void InitServer(::grpc_impl::ServerInitializer* si) override;
void Finish(::grpc_impl::ServerInitializer* si) override;
void ChangeArguments(const ::grpc::string& name, void* value) override;
bool has_async_methods() const override;
bool has_sync_methods() const override;
private:
std::shared_ptr<grpc::ProtoServerReflection> reflection_service_;
};
typedef ::grpc_impl::reflection::ProtoServerReflectionPlugin
ProtoServerReflectionPlugin;
/// Add proto reflection plugin to \a ServerBuilder.
/// This function should be called at the static initialization time.
void InitProtoReflectionServerBuilderPlugin();
static inline void InitProtoReflectionServerBuilderPlugin() {
::grpc_impl::reflection::InitProtoReflectionServerBuilderPlugin();
}
} // namespace reflection
} // namespace grpc

@ -0,0 +1,55 @@
/*
*
* Copyright 2015 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.
*
*/
#ifndef GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H
#define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H
#include <grpcpp/impl/server_builder_plugin.h>
#include <grpcpp/support/config.h>
namespace grpc {
class ProtoServerReflection;
} // namespace grpc
namespace grpc_impl {
class ServerInitializer;
namespace reflection {
class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
public:
ProtoServerReflectionPlugin();
::grpc::string name() override;
void InitServer(::grpc_impl::ServerInitializer* si) override;
void Finish(::grpc_impl::ServerInitializer* si) override;
void ChangeArguments(const ::grpc::string& name, void* value) override;
bool has_async_methods() const override;
bool has_sync_methods() const override;
private:
std::shared_ptr<grpc::ProtoServerReflection> reflection_service_;
};
/// Add proto reflection plugin to \a ServerBuilder.
/// This function should be called at the static initialization time.
void InitProtoReflectionServerBuilderPlugin();
} // namespace reflection
} // namespace grpc_impl
#endif // GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_IMPL_H

@ -19,85 +19,11 @@
#ifndef GRPCPP_GENERIC_GENERIC_STUB_H
#define GRPCPP_GENERIC_GENERIC_STUB_H
#include <functional>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/support/byte_buffer.h>
#include <grpcpp/support/client_callback.h>
#include <grpcpp/support/status.h>
#include <grpcpp/generic/generic_stub_impl.h>
namespace grpc {
class CompletionQueue;
typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter;
typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
/// Generic stubs provide a type-unsafe interface to call gRPC methods
/// by name.
class GenericStub final {
public:
explicit GenericStub(std::shared_ptr<ChannelInterface> channel)
: channel_(channel) {}
/// Setup a call to a named method \a method using \a context, but don't
/// start it. Let it be started explicitly with StartCall and a tag.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<GenericClientAsyncReaderWriter> PrepareCall(
ClientContext* context, const grpc::string& method, CompletionQueue* cq);
/// Setup a unary call to a named method \a method using \a context, and don't
/// start it. Let it be started explicitly with StartCall.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<GenericClientAsyncResponseReader> PrepareUnaryCall(
ClientContext* context, const grpc::string& method,
const ByteBuffer& request, CompletionQueue* cq);
/// DEPRECATED for multi-threaded use
/// Begin a call to a named method \a method using \a context.
/// A tag \a tag will be delivered to \a cq when the call has been started
/// (i.e, initial metadata has been sent).
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<GenericClientAsyncReaderWriter> Call(
ClientContext* context, const grpc::string& method, CompletionQueue* cq,
void* tag);
/// NOTE: class experimental_type is not part of the public API of this class
/// TODO(vjpai): Move these contents to the public API of GenericStub when
/// they are no longer experimental
class experimental_type {
public:
explicit experimental_type(GenericStub* stub) : stub_(stub) {}
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(ClientContext* context, const grpc::string& method,
const ByteBuffer* request, ByteBuffer* response,
std::function<void(Status)> on_completion);
/// Setup a call to a named method \a method using \a context and tied to
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
ClientContext* context, const grpc::string& method,
experimental::ClientBidiReactor<ByteBuffer, ByteBuffer>* reactor);
private:
GenericStub* stub_;
};
/// NOTE: The function experimental() is not stable public API. It is a view
/// to the experimental components of this class. It may be changed or removed
/// at any time.
experimental_type experimental() { return experimental_type(this); }
private:
std::shared_ptr<ChannelInterface> channel_;
};
typedef ::grpc_impl::GenericStub GenericStub;
} // namespace grpc

@ -0,0 +1,108 @@
/*
*
* Copyright 2015 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.
*
*/
#ifndef GRPCPP_GENERIC_GENERIC_STUB_IMPL_H
#define GRPCPP_GENERIC_GENERIC_STUB_IMPL_H
#include <functional>
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/support/byte_buffer.h>
#include <grpcpp/support/client_callback.h>
#include <grpcpp/support/status.h>
namespace grpc {
class CompletionQueue;
typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter;
typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
} // namespace grpc
namespace grpc_impl {
/// Generic stubs provide a type-unsafe interface to call gRPC methods
/// by name.
class GenericStub final {
public:
explicit GenericStub(std::shared_ptr<grpc::ChannelInterface> channel)
: channel_(channel) {}
/// Setup a call to a named method \a method using \a context, but don't
/// start it. Let it be started explicitly with StartCall and a tag.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> PrepareCall(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq);
/// Setup a unary call to a named method \a method using \a context, and don't
/// start it. Let it be started explicitly with StartCall.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncResponseReader> PrepareUnaryCall(
grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer& request, grpc::CompletionQueue* cq);
/// DEPRECATED for multi-threaded use
/// Begin a call to a named method \a method using \a context.
/// A tag \a tag will be delivered to \a cq when the call has been started
/// (i.e, initial metadata has been sent).
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> Call(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq, void* tag);
/// NOTE: class experimental_type is not part of the public API of this class
/// TODO(vjpai): Move these contents to the public API of GenericStub when
/// they are no longer experimental
class experimental_type {
public:
explicit experimental_type(GenericStub* stub) : stub_(stub) {}
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion);
/// Setup a call to a named method \a method using \a context and tied to
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
grpc::ClientContext* context, const grpc::string& method,
grpc::experimental::ClientBidiReactor<grpc::ByteBuffer,
grpc::ByteBuffer>* reactor);
private:
GenericStub* stub_;
};
/// NOTE: The function experimental() is not stable public API. It is a view
/// to the experimental components of this class. It may be changed or removed
/// at any time.
experimental_type experimental() { return experimental_type(this); }
private:
std::shared_ptr<grpc::ChannelInterface> channel_;
};
} // namespace grpc_impl
#endif // GRPCPP_GENERIC_GENERIC_STUB_IMPL_H

@ -28,6 +28,10 @@
#include <grpcpp/impl/codegen/rpc_service_method.h>
#include <grpcpp/impl/codegen/server_context.h>
namespace grpc_impl {
class ServerCredentials;
}
namespace grpc {
class AsyncGenericService;
@ -35,7 +39,6 @@ class Channel;
class GenericServerContext;
class ServerCompletionQueue;
class ServerContext;
class ServerCredentials;
class Service;
extern CoreCodegenInterface* g_core_codegen_interface;
@ -150,7 +153,7 @@ class ServerInterface : public internal::CallHook {
///
/// \warning It's an error to call this method on an already started server.
virtual int AddListeningPort(const grpc::string& addr,
ServerCredentials* creds) = 0;
grpc_impl::ServerCredentials* creds) = 0;
/// Start the server.
///

@ -1,6 +1,6 @@
/*
*
* Copyright 2015 gRPC authors.
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,14 +19,7 @@
#ifndef GRPCPP_SECURITY_SERVER_CREDENTIALS_H
#define GRPCPP_SECURITY_SERVER_CREDENTIALS_H
#include <memory>
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/security/auth_metadata_processor.h>
#include <grpcpp/support/config.h>
struct grpc_server;
#include <grpcpp/security/server_credentials_impl.h>
namespace grpc_impl {
@ -34,27 +27,7 @@ class Server;
} // namespace grpc_impl
namespace grpc {
/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
class ServerCredentials {
public:
virtual ~ServerCredentials();
/// This method is not thread-safe and has to be called before the server is
/// started. The last call to this function wins.
virtual void SetAuthMetadataProcessor(
const std::shared_ptr<AuthMetadataProcessor>& processor) = 0;
private:
friend class ::grpc_impl::Server;
/// Tries to bind \a server to the given \a addr (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.)
///
/// \return bound port number on sucess, 0 on failure.
// TODO(dgq): the "port" part seems to be a misnomer.
virtual int AddPortToServer(const grpc::string& addr,
grpc_server* server) = 0;
};
typedef ::grpc_impl::ServerCredentials ServerCredentials;
/// Options to create ServerCredentials with SSL
struct SslServerCredentialsOptions {
@ -82,27 +55,29 @@ struct SslServerCredentialsOptions {
grpc_ssl_client_certificate_request_type client_certificate_request;
};
/// Builds SSL ServerCredentials given SSL specific options
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options);
static inline std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options) {
return ::grpc_impl::SslServerCredentials(options);
}
/// Builds insecure server credentials.
std::shared_ptr<ServerCredentials> InsecureServerCredentials();
static inline std::shared_ptr<ServerCredentials> InsecureServerCredentials() {
return ::grpc_impl::InsecureServerCredentials();
}
namespace experimental {
/// Options to create ServerCredentials with ALTS
struct AltsServerCredentialsOptions {
/// Add fields if needed.
};
typedef ::grpc_impl::experimental::AltsServerCredentialsOptions
AltsServerCredentialsOptions;
/// Builds ALTS ServerCredentials given ALTS specific options
std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options);
static inline std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options) {
return ::grpc_impl::experimental::AltsServerCredentials(options);
}
/// Builds Local ServerCredentials.
std::shared_ptr<ServerCredentials> LocalServerCredentials(
grpc_local_connect_type type);
static inline std::shared_ptr<ServerCredentials> LocalServerCredentials(
grpc_local_connect_type type) {
return ::grpc_impl::experimental::LocalServerCredentials(type);
}
} // namespace experimental
} // namespace grpc

@ -0,0 +1,85 @@
/*
*
* Copyright 2015 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.
*
*/
#ifndef GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H
#define GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H
#include <memory>
#include <vector>
#include <grpc/grpc_security_constants.h>
#include <grpcpp/security/auth_metadata_processor.h>
#include <grpcpp/support/config.h>
struct grpc_server;
namespace grpc {
struct SslServerCredentialsOptions;
} // namespace grpc
namespace grpc_impl {
class Server;
/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
class ServerCredentials {
public:
virtual ~ServerCredentials();
/// This method is not thread-safe and has to be called before the server is
/// started. The last call to this function wins.
virtual void SetAuthMetadataProcessor(
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) = 0;
private:
friend class ::grpc_impl::Server;
/// Tries to bind \a server to the given \a addr (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.)
///
/// \return bound port number on sucess, 0 on failure.
// TODO(dgq): the "port" part seems to be a misnomer.
virtual int AddPortToServer(const grpc::string& addr,
grpc_server* server) = 0;
};
/// Builds SSL ServerCredentials given SSL specific options
std::shared_ptr<ServerCredentials> SslServerCredentials(
const grpc::SslServerCredentialsOptions& options);
/// Builds insecure server credentials.
std::shared_ptr<ServerCredentials> InsecureServerCredentials();
namespace experimental {
/// Options to create ServerCredentials with ALTS
struct AltsServerCredentialsOptions {
/// Add fields if needed.
};
/// Builds ALTS ServerCredentials given ALTS specific options
std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options);
/// Builds Local ServerCredentials.
std::shared_ptr<ServerCredentials> LocalServerCredentials(
grpc_local_connect_type type);
} // namespace experimental
} // namespace grpc_impl
#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_IMPL_H

@ -38,14 +38,15 @@ struct grpc_resource_quota;
namespace grpc_impl {
class Server;
class ServerCredentials;
class ResourceQuota;
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
class CompletionQueue;
class ServerCompletionQueue;
class ServerCredentials;
class Service;
namespace testing {
@ -96,9 +97,10 @@ class ServerBuilder {
/// number bound to the \a grpc::Server for the corresponding endpoint after
/// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort
/// does not modify this pointer.
ServerBuilder& AddListeningPort(const grpc::string& addr_uri,
std::shared_ptr<ServerCredentials> creds,
int* selected_port = nullptr);
ServerBuilder& AddListeningPort(
const grpc::string& addr_uri,
std::shared_ptr<grpc_impl::ServerCredentials> creds,
int* selected_port = nullptr);
/// Add a completion queue for handling asynchronous services.
///
@ -255,7 +257,7 @@ class ServerBuilder {
/// Experimental, to be deprecated
struct Port {
grpc::string addr;
std::shared_ptr<ServerCredentials> creds;
std::shared_ptr<grpc_impl::ServerCredentials> creds;
int* selected_port;
};
@ -323,7 +325,7 @@ class ServerBuilder {
/// List of completion queues added via \a AddCompletionQueue method.
std::vector<ServerCompletionQueue*> cqs_;
std::shared_ptr<ServerCredentials> creds_;
std::shared_ptr<grpc_impl::ServerCredentials> creds_;
std::vector<std::unique_ptr<ServerBuilderPlugin>> plugins_;
grpc_resource_quota* resource_quota_;
AsyncGenericService* generic_service_{nullptr};

@ -149,45 +149,48 @@ struct QueuedPick {
};
struct client_channel_channel_data {
//
// Fields set at construction and never modified.
//
bool deadline_checking_enabled;
bool enable_retries;
size_t per_rpc_retry_buffer_size;
/** combiner protecting all variables below in this data structure */
grpc_combiner* combiner;
/** owning stack */
grpc_channel_stack* owning_stack;
/** interested parties (owned) */
grpc_pollset_set* interested_parties;
// Client channel factory.
grpc_core::ClientChannelFactory* client_channel_factory;
// Subchannel pool.
grpc_core::RefCountedPtr<grpc_core::SubchannelPoolInterface> subchannel_pool;
grpc_core::channelz::ClientChannelNode* channelz_node;
// Resolving LB policy.
grpc_core::OrphanablePtr<LoadBalancingPolicy> resolving_lb_policy;
// Subchannel picker from LB policy.
//
// Fields used in the data plane. Protected by data_plane_combiner.
//
grpc_combiner* data_plane_combiner;
grpc_core::UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker;
// Linked list of queued picks.
QueuedPick* queued_picks;
bool have_service_config;
/** retry throttle data from service config */
QueuedPick* queued_picks; // Linked list of queued picks.
// Data from service config.
bool received_service_config_data;
grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
/** per-method service config data */
grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table;
/* the following properties are guarded by a mutex since APIs require them
to be instantaneously available */
//
// Fields used in the control plane. Protected by combiner.
//
grpc_combiner* combiner;
grpc_pollset_set* interested_parties;
grpc_core::RefCountedPtr<grpc_core::SubchannelPoolInterface> subchannel_pool;
grpc_core::OrphanablePtr<LoadBalancingPolicy> resolving_lb_policy;
grpc_connectivity_state_tracker state_tracker;
//
// Fields accessed from both data plane and control plane combiners.
//
grpc_core::Atomic<grpc_error*> disconnect_error;
// The following properties are guarded by a mutex since APIs require them
// to be instantaneously available.
gpr_mu info_mu;
grpc_core::UniquePtr<char> info_lb_policy_name;
grpc_core::UniquePtr<char> info_service_config_json;
grpc_connectivity_state_tracker state_tracker;
grpc_error* disconnect_error;
grpc_core::ManualConstructor<
grpc_core::ExternalConnectivityWatcher::WatcherList>
external_connectivity_watcher_list;
@ -214,30 +217,98 @@ static const char* get_channel_connectivity_state_change_string(
GPR_UNREACHABLE_CODE(return "UNKNOWN");
}
static void set_connectivity_state_and_picker_locked(
channel_data* chand, grpc_connectivity_state state, grpc_error* state_error,
const char* reason,
grpc_core::UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker) {
// Update connectivity state.
grpc_connectivity_state_set(&chand->state_tracker, state, state_error,
reason);
if (chand->channelz_node != nullptr) {
chand->channelz_node->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
get_channel_connectivity_state_change_string(state)));
namespace grpc_core {
namespace {
// A fire-and-forget class that sets the channel's connectivity state
// and then hops into the data plane combiner to update the picker.
// Must be instantiated while holding the control plane combiner.
// Deletes itself when done.
class ConnectivityStateAndPickerSetter {
public:
ConnectivityStateAndPickerSetter(
channel_data* chand, grpc_connectivity_state state,
grpc_error* state_error, const char* reason,
UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker)
: chand_(chand), picker_(std::move(picker)) {
// Update connectivity state here, while holding control plane combiner.
grpc_connectivity_state_set(&chand->state_tracker, state, state_error,
reason);
if (chand->channelz_node != nullptr) {
chand->channelz_node->AddTraceEvent(
channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string(
get_channel_connectivity_state_change_string(state)));
}
// Bounce into the data plane combiner to reset the picker.
GRPC_CHANNEL_STACK_REF(chand->owning_stack,
"ConnectivityStateAndPickerSetter");
GRPC_CLOSURE_INIT(&closure_, SetPicker, this,
grpc_combiner_scheduler(chand->data_plane_combiner));
GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE);
}
// Update picker.
chand->picker = std::move(picker);
// Re-process queued picks.
for (QueuedPick* pick = chand->queued_picks; pick != nullptr;
pick = pick->next) {
start_pick_locked(pick->elem, GRPC_ERROR_NONE);
private:
static void SetPicker(void* arg, grpc_error* ignored) {
auto* self = static_cast<ConnectivityStateAndPickerSetter*>(arg);
// Update picker.
self->chand_->picker = std::move(self->picker_);
// Re-process queued picks.
for (QueuedPick* pick = self->chand_->queued_picks; pick != nullptr;
pick = pick->next) {
start_pick_locked(pick->elem, GRPC_ERROR_NONE);
}
// Clean up.
GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack,
"ConnectivityStateAndPickerSetter");
Delete(self);
}
}
namespace grpc_core {
namespace {
channel_data* chand_;
UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker_;
grpc_closure closure_;
};
// A fire-and-forget class that sets the channel's service config data
// in the data plane combiner. Deletes itself when done.
class ServiceConfigSetter {
public:
ServiceConfigSetter(
channel_data* chand,
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
RefCountedPtr<ClientChannelMethodParamsTable> method_params_table)
: chand_(chand),
retry_throttle_data_(std::move(retry_throttle_data)),
method_params_table_(std::move(method_params_table)) {
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "ServiceConfigSetter");
GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this,
grpc_combiner_scheduler(chand->data_plane_combiner));
GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE);
}
private:
static void SetServiceConfigData(void* arg, grpc_error* ignored) {
ServiceConfigSetter* self = static_cast<ServiceConfigSetter*>(arg);
channel_data* chand = self->chand_;
// Update channel state.
chand->received_service_config_data = true;
chand->retry_throttle_data = std::move(self->retry_throttle_data_);
chand->method_params_table = std::move(self->method_params_table_);
// Apply service config to queued picks.
for (QueuedPick* pick = chand->queued_picks; pick != nullptr;
pick = pick->next) {
maybe_apply_service_config_to_call_locked(pick->elem);
}
// Clean up.
GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack, "ServiceConfigSetter");
Delete(self);
}
channel_data* chand_;
RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
RefCountedPtr<ClientChannelMethodParamsTable> method_params_table_;
grpc_closure closure_;
};
//
// ExternalConnectivityWatcher::WatcherList
@ -387,8 +458,10 @@ class ClientChannelControlHelper
void UpdateState(
grpc_connectivity_state state, grpc_error* state_error,
UniquePtr<LoadBalancingPolicy::SubchannelPicker> picker) override {
grpc_error* disconnect_error =
chand_->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE);
if (grpc_client_channel_routing_trace.enabled()) {
const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE
const char* extra = disconnect_error == GRPC_ERROR_NONE
? ""
: " (ignoring -- channel shutting down)";
gpr_log(GPR_INFO, "chand=%p: update: state=%s error=%s picker=%p%s",
@ -396,9 +469,10 @@ class ClientChannelControlHelper
grpc_error_string(state_error), picker.get(), extra);
}
// Do update only if not shutting down.
if (chand_->disconnect_error == GRPC_ERROR_NONE) {
set_connectivity_state_and_picker_locked(chand_, state, state_error,
"helper", std::move(picker));
if (disconnect_error == GRPC_ERROR_NONE) {
// Will delete itself.
New<ConnectivityStateAndPickerSetter>(chand_, state, state_error,
"helper", std::move(picker));
} else {
GRPC_ERROR_UNREF(state_error);
}
@ -420,7 +494,6 @@ static bool process_resolver_result_locked(
void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name,
grpc_core::RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
channel_data* chand = static_cast<channel_data*>(arg);
chand->have_service_config = true;
ProcessedResolverResult resolver_result(result, chand->enable_retries);
grpc_core::UniquePtr<char> service_config_json =
resolver_result.service_config_json();
@ -428,9 +501,11 @@ static bool process_resolver_result_locked(
gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
chand, service_config_json.get());
}
// Update channel state.
chand->retry_throttle_data = resolver_result.retry_throttle_data();
chand->method_params_table = resolver_result.method_params_table();
// Create service config setter to update channel state in the data
// plane combiner. Destroys itself when done.
grpc_core::New<grpc_core::ServiceConfigSetter>(
chand, resolver_result.retry_throttle_data(),
resolver_result.method_params_table());
// Swap out the data used by cc_get_channel_info().
gpr_mu_lock(&chand->info_mu);
chand->info_lb_policy_name = resolver_result.lb_policy_name();
@ -445,11 +520,6 @@ static bool process_resolver_result_locked(
// Return results.
*lb_policy_name = chand->info_lb_policy_name.get();
*lb_policy_config = resolver_result.lb_policy_config();
// Apply service config to queued picks.
for (QueuedPick* pick = chand->queued_picks; pick != nullptr;
pick = pick->next) {
maybe_apply_service_config_to_call_locked(pick->elem);
}
return service_config_changed;
}
@ -507,12 +577,16 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
}
if (op->disconnect_with_error != GRPC_ERROR_NONE) {
chand->disconnect_error = op->disconnect_with_error;
grpc_error* error = GRPC_ERROR_NONE;
GPR_ASSERT(chand->disconnect_error.CompareExchangeStrong(
&error, op->disconnect_with_error, grpc_core::MemoryOrder::ACQ_REL,
grpc_core::MemoryOrder::ACQUIRE));
grpc_pollset_set_del_pollset_set(
chand->resolving_lb_policy->interested_parties(),
chand->interested_parties);
chand->resolving_lb_policy.reset();
set_connectivity_state_and_picker_locked(
// Will delete itself.
grpc_core::New<grpc_core::ConnectivityStateAndPickerSetter>(
chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error),
"shutdown from API",
grpc_core::UniquePtr<LoadBalancingPolicy::SubchannelPicker>(
@ -562,10 +636,12 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
// Initialize data members.
chand->data_plane_combiner = grpc_combiner_create();
chand->combiner = grpc_combiner_create();
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
chand->disconnect_error = GRPC_ERROR_NONE;
chand->disconnect_error.Store(GRPC_ERROR_NONE,
grpc_core::MemoryOrder::RELAXED);
gpr_mu_init(&chand->info_mu);
chand->external_connectivity_watcher_list.Init();
chand->owning_stack = args->channel_stack;
@ -671,8 +747,10 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
chand->method_params_table.reset();
grpc_client_channel_stop_backup_polling(chand->interested_parties);
grpc_pollset_set_destroy(chand->interested_parties);
GRPC_COMBINER_UNREF(chand->data_plane_combiner, "client_channel");
GRPC_COMBINER_UNREF(chand->combiner, "client_channel");
GRPC_ERROR_UNREF(chand->disconnect_error);
GRPC_ERROR_UNREF(
chand->disconnect_error.Load(grpc_core::MemoryOrder::RELAXED));
grpc_connectivity_state_destroy(&chand->state_tracker);
gpr_mu_destroy(&chand->info_mu);
chand->external_connectivity_watcher_list.Destroy();
@ -1421,7 +1499,7 @@ static void do_retry(grpc_call_element* elem,
}
// Schedule retry after computed delay.
GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem,
grpc_combiner_scheduler(chand->combiner));
grpc_combiner_scheduler(chand->data_plane_combiner));
grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure);
// Update bookkeeping.
if (retry_state != nullptr) retry_state->retry_dispatched = true;
@ -2648,7 +2726,7 @@ class QueuedPickCanceller {
auto* chand = static_cast<channel_data*>(elem->channel_data);
GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller");
GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this,
grpc_combiner_scheduler(chand->combiner));
grpc_combiner_scheduler(chand->data_plane_combiner));
grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_);
}
@ -2788,7 +2866,7 @@ static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) {
call_data* calld = static_cast<call_data*>(elem->call_data);
// Apply service config data to the call only once, and only if the
// channel has the data available.
if (GPR_LIKELY(chand->have_service_config &&
if (GPR_LIKELY(chand->received_service_config_data &&
!calld->service_config_applied)) {
calld->service_config_applied = true;
apply_service_config_to_call_locked(elem);
@ -2836,7 +2914,7 @@ static void start_pick_locked(void* arg, grpc_error* error) {
.send_initial_metadata_flags;
// Apply service config to call if needed.
maybe_apply_service_config_to_call_locked(elem);
// When done, we schedule this closure to leave the channel combiner.
// When done, we schedule this closure to leave the data plane combiner.
GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem,
grpc_schedule_on_exec_ctx);
// Attempt pick.
@ -2851,12 +2929,14 @@ static void start_pick_locked(void* arg, grpc_error* error) {
grpc_error_string(error));
}
switch (pick_result) {
case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE:
case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: {
// If we're shutting down, fail all RPCs.
if (chand->disconnect_error != GRPC_ERROR_NONE) {
grpc_error* disconnect_error =
chand->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE);
if (disconnect_error != GRPC_ERROR_NONE) {
GRPC_ERROR_UNREF(error);
GRPC_CLOSURE_SCHED(&calld->pick_closure,
GRPC_ERROR_REF(chand->disconnect_error));
GRPC_ERROR_REF(disconnect_error));
break;
}
// If wait_for_ready is false, then the error indicates the RPC
@ -2882,7 +2962,8 @@ static void start_pick_locked(void* arg, grpc_error* error) {
// If wait_for_ready is true, then queue to retry when we get a new
// picker.
GRPC_ERROR_UNREF(error);
// Fallthrough
}
// Fallthrough
case LoadBalancingPolicy::PICK_QUEUE:
if (!calld->pick_queued) add_call_to_queued_picks_locked(elem);
break;
@ -2976,7 +3057,8 @@ static void cc_start_transport_stream_op_batch(
}
GRPC_CLOSURE_SCHED(
GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_pick_locked,
elem, grpc_combiner_scheduler(chand->combiner)),
elem,
grpc_combiner_scheduler(chand->data_plane_combiner)),
GRPC_ERROR_NONE);
} else {
// For all other batches, release the call combiner.

@ -287,7 +287,6 @@ HealthCheckClient::CallState::CallState(
->GetInitialCallSizeEstimate(0))),
payload_(context_) {
grpc_call_combiner_init(&call_combiner_);
gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(0));
}
HealthCheckClient::CallState::~CallState() {
@ -295,9 +294,6 @@ HealthCheckClient::CallState::~CallState() {
gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p",
health_check_client_.get(), this);
}
// The subchannel call is in the arena, so reset the pointer before we destroy
// the arena.
call_.reset();
for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) {
if (context_[i].destroy != nullptr) {
context_[i].destroy(context_[i].value);
@ -436,12 +432,22 @@ void HealthCheckClient::CallState::StartBatch(
GRPC_ERROR_NONE, "start_subchannel_batch");
}
void HealthCheckClient::CallState::AfterCallStackDestruction(
void* arg, grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
self->Unref(DEBUG_LOCATION, "cancel");
}
void HealthCheckClient::CallState::OnCancelComplete(void* arg,
grpc_error* error) {
HealthCheckClient::CallState* self =
static_cast<HealthCheckClient::CallState*>(arg);
GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel");
self->Unref(DEBUG_LOCATION, "cancel");
GRPC_CLOSURE_INIT(&self->after_call_stack_destruction_,
AfterCallStackDestruction, self, grpc_schedule_on_exec_ctx);
self->call_->SetAfterCallStackDestroy(&self->after_call_stack_destruction_);
self->call_.reset();
}
void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) {
@ -455,7 +461,9 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) {
}
void HealthCheckClient::CallState::Cancel() {
if (call_ != nullptr) {
bool expected = false;
if (cancelled_.CompareExchangeStrong(&expected, true, MemoryOrder::ACQ_REL,
MemoryOrder::ACQUIRE)) {
Ref(DEBUG_LOCATION, "cancel").release();
GRPC_CALL_COMBINER_START(
&call_combiner_,
@ -498,7 +506,7 @@ void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy");
}
health_check_client_->SetHealthStatus(state, error);
gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(1));
seen_response_.Store(true, MemoryOrder::RELEASE);
grpc_slice_buffer_destroy_internal(&recv_message_buffer_);
// Start another recv_message batch.
// This re-uses the ref we're holding.
@ -631,7 +639,7 @@ void HealthCheckClient::CallState::CallEnded(bool retry) {
health_check_client_->call_state_.reset();
if (retry) {
GPR_ASSERT(!health_check_client_->shutting_down_);
if (static_cast<bool>(gpr_atm_acq_load(&seen_response_))) {
if (seen_response_.Load(MemoryOrder::ACQUIRE)) {
// If the call fails after we've gotten a successful response, reset
// the backoff and restart the call immediately.
health_check_client_->retry_backoff_.Reset();

@ -22,13 +22,13 @@
#include <grpc/support/port_platform.h>
#include <grpc/grpc.h>
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
#include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/call_combiner.h"
@ -91,6 +91,8 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
grpc_error* PullSliceFromRecvMessage();
void DoneReadingRecvMessage(grpc_error* error);
static void AfterCallStackDestruction(void* arg, grpc_error* error);
RefCountedPtr<HealthCheckClient> health_check_client_;
grpc_polling_entity pollent_;
@ -126,12 +128,18 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
OrphanablePtr<ByteStream> recv_message_;
grpc_closure recv_message_ready_;
grpc_slice_buffer recv_message_buffer_;
gpr_atm seen_response_;
Atomic<bool> seen_response_{false};
// recv_trailing_metadata
grpc_metadata_batch recv_trailing_metadata_;
grpc_transport_stream_stats collect_stats_;
grpc_closure recv_trailing_metadata_ready_;
// True if the cancel_stream batch has been started.
Atomic<bool> cancelled_{false};
// Closure for call stack destruction.
grpc_closure after_call_stack_destruction_;
};
void StartCall();

@ -140,10 +140,9 @@ LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick(
// the time this function returns, the pick will already have
// been processed, and we'll be trying to re-process the same
// pick again, leading to a crash.
// 2. In a subsequent PR, we will split the data plane and control
// plane synchronization into separate combiners, at which
// point this will need to hop from the data plane combiner into
// the control plane combiner.
// 2. We are currently running in the data plane combiner, but we
// need to bounce into the control plane combiner to call
// ExitIdleLocked().
if (!exit_idle_called_) {
exit_idle_called_ = true;
parent_->Ref().release(); // ref held by closure.

@ -234,12 +234,19 @@ class GrpcLb : public LoadBalancingPolicy {
// Returns the LB token to use for a drop, or null if the call
// should not be dropped.
// Intended to be called from picker, so calls will be externally
// synchronized.
//
// Note: This is called from the picker, so it will be invoked in
// the channel's data plane combiner, NOT the control plane
// combiner. It should not be accessed by any other part of the LB
// policy.
const char* ShouldDrop();
private:
grpc_grpclb_serverlist* serverlist_;
// Guarded by the channel's data plane combiner, NOT the control
// plane combiner. It should not be accessed by anything but the
// picker via the ShouldDrop() method.
size_t drop_index_ = 0;
};
@ -551,7 +558,7 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs* pick, grpc_error** error) {
// subchannel call (and therefore no client_load_reporting filter)
// for dropped calls.
if (client_stats_ != nullptr) {
client_stats_->AddCallDroppedLocked(drop_token);
client_stats_->AddCallDropped(drop_token);
}
return PICK_COMPLETE;
}
@ -910,7 +917,7 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() {
// Construct message payload.
GPR_ASSERT(send_message_payload_ == nullptr);
grpc_grpclb_request* request =
grpc_grpclb_load_report_request_create_locked(client_stats_.get());
grpc_grpclb_load_report_request_create(client_stats_.get());
// Skip client load report if the counters were all zero in the last
// report and they are still zero in this one.
if (LoadReportCountersAreZero(request)) {

@ -25,6 +25,8 @@
#include <grpc/support/atm.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gprpp/mutex_lock.h"
namespace grpc_core {
void GrpcLbClientStats::AddCallStarted() {
@ -43,11 +45,12 @@ void GrpcLbClientStats::AddCallFinished(
}
}
void GrpcLbClientStats::AddCallDroppedLocked(const char* token) {
void GrpcLbClientStats::AddCallDropped(const char* token) {
// Increment num_calls_started and num_calls_finished.
gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1);
gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1);
// Record the drop.
MutexLock lock(&drop_count_mu_);
if (drop_token_counts_ == nullptr) {
drop_token_counts_.reset(New<DroppedCallCounts>());
}
@ -69,7 +72,7 @@ void AtomicGetAndResetCounter(int64_t* value, gpr_atm* counter) {
} // namespace
void GrpcLbClientStats::GetLocked(
void GrpcLbClientStats::Get(
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,
@ -80,6 +83,7 @@ void GrpcLbClientStats::GetLocked(
&num_calls_finished_with_client_failed_to_send_);
AtomicGetAndResetCounter(num_calls_finished_known_received,
&num_calls_finished_known_received_);
MutexLock lock(&drop_count_mu_);
*drop_token_counts = std::move(drop_token_counts_);
}

@ -41,20 +41,19 @@ class GrpcLbClientStats : public RefCounted<GrpcLbClientStats> {
typedef InlinedVector<DropTokenCount, 10> DroppedCallCounts;
GrpcLbClientStats() {}
GrpcLbClientStats() { gpr_mu_init(&drop_count_mu_); }
~GrpcLbClientStats() { gpr_mu_destroy(&drop_count_mu_); }
void AddCallStarted();
void AddCallFinished(bool finished_with_client_failed_to_send,
bool finished_known_received);
// This method is not thread-safe; caller must synchronize.
void AddCallDroppedLocked(const char* token);
void AddCallDropped(const char* token);
// This method is not thread-safe; caller must synchronize.
void GetLocked(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<DroppedCallCounts>* drop_token_counts);
void Get(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<DroppedCallCounts>* drop_token_counts);
// A destruction function to use as the user_data key when attaching
// client stats to a grpc_mdelem.
@ -63,13 +62,12 @@ class GrpcLbClientStats : public RefCounted<GrpcLbClientStats> {
}
private:
// This field must only be accessed via *_locked() methods.
UniquePtr<DroppedCallCounts> drop_token_counts_;
// These fields may be accessed from multiple threads at a time.
gpr_atm num_calls_started_ = 0;
gpr_atm num_calls_finished_ = 0;
gpr_atm num_calls_finished_with_client_failed_to_send_ = 0;
gpr_atm num_calls_finished_known_received_ = 0;
gpr_mu drop_count_mu_; // Guards drop_token_counts_.
UniquePtr<DroppedCallCounts> drop_token_counts_;
};
} // namespace grpc_core

@ -107,7 +107,7 @@ static bool encode_drops(pb_ostream_t* stream, const pb_field_t* field,
return true;
}
grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
grpc_grpclb_request* grpc_grpclb_load_report_request_create(
grpc_core::GrpcLbClientStats* client_stats) {
grpc_grpclb_request* req = static_cast<grpc_grpclb_request*>(
gpr_zalloc(sizeof(grpc_grpclb_request)));
@ -122,7 +122,7 @@ grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
req->client_stats.calls_finished_with_drop.funcs.encode = encode_drops;
grpc_core::UniquePtr<grpc_core::GrpcLbClientStats::DroppedCallCounts>
drop_counts;
client_stats->GetLocked(
client_stats->Get(
&req->client_stats.num_calls_started,
&req->client_stats.num_calls_finished,
&req->client_stats.num_calls_finished_with_client_failed_to_send,

@ -43,7 +43,7 @@ typedef struct {
/** Create a request for a gRPC LB service under \a lb_service_name */
grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name);
grpc_grpclb_request* grpc_grpclb_load_report_request_create_locked(
grpc_grpclb_request* grpc_grpclb_load_report_request_create(
grpc_core::GrpcLbClientStats* client_stats);
/** Protocol Buffers v3-encode \a request */

@ -186,6 +186,7 @@ void PickFirst::ShutdownLocked() {
}
void PickFirst::ExitIdleLocked() {
if (shutdown_) return;
if (idle_) {
idle_ = false;
if (subchannel_list_ == nullptr ||

@ -22,63 +22,75 @@
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/support/client_callback.h>
namespace grpc {
namespace grpc_impl {
namespace {
std::unique_ptr<GenericClientAsyncReaderWriter> CallInternal(
ChannelInterface* channel, ClientContext* context,
const grpc::string& method, CompletionQueue* cq, bool start, void* tag) {
return std::unique_ptr<GenericClientAsyncReaderWriter>(
internal::ClientAsyncReaderWriterFactory<ByteBuffer, ByteBuffer>::Create(
channel, cq,
internal::RpcMethod(method.c_str(),
internal::RpcMethod::BIDI_STREAMING),
context, start, tag));
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> CallInternal(
grpc::ChannelInterface* channel, grpc::ClientContext* context,
const grpc::string& method, grpc::CompletionQueue* cq, bool start,
void* tag) {
return std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
grpc::internal::ClientAsyncReaderWriterFactory<grpc::ByteBuffer,
grpc::ByteBuffer>::
Create(channel, cq,
grpc::internal::RpcMethod(
method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING),
context, start, tag));
}
} // namespace
// begin a call to a named method
std::unique_ptr<GenericClientAsyncReaderWriter> GenericStub::Call(
ClientContext* context, const grpc::string& method, CompletionQueue* cq,
void* tag) {
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> GenericStub::Call(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq, void* tag) {
return CallInternal(channel_.get(), context, method, cq, true, tag);
}
// setup a call to a named method
std::unique_ptr<GenericClientAsyncReaderWriter> GenericStub::PrepareCall(
ClientContext* context, const grpc::string& method, CompletionQueue* cq) {
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> GenericStub::PrepareCall(
grpc::ClientContext* context, const grpc::string& method,
grpc::CompletionQueue* cq) {
return CallInternal(channel_.get(), context, method, cq, false, nullptr);
}
// setup a unary call to a named method
std::unique_ptr<GenericClientAsyncResponseReader> GenericStub::PrepareUnaryCall(
ClientContext* context, const grpc::string& method,
const ByteBuffer& request, CompletionQueue* cq) {
return std::unique_ptr<GenericClientAsyncResponseReader>(
internal::ClientAsyncResponseReaderFactory<ByteBuffer>::Create(
channel_.get(), cq,
internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC),
context, request, false));
std::unique_ptr<grpc::GenericClientAsyncResponseReader>
GenericStub::PrepareUnaryCall(grpc::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer& request,
grpc::CompletionQueue* cq) {
return std::unique_ptr<grpc::GenericClientAsyncResponseReader>(
grpc::internal::ClientAsyncResponseReaderFactory<
grpc::ByteBuffer>::Create(channel_.get(), cq,
grpc::internal::RpcMethod(
method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, false));
}
void GenericStub::experimental_type::UnaryCall(
ClientContext* context, const grpc::string& method,
const ByteBuffer* request, ByteBuffer* response,
std::function<void(Status)> on_completion) {
internal::CallbackUnaryCall(
grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion) {
grpc::internal::CallbackUnaryCall(
stub_->channel_.get(),
internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC),
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, response, std::move(on_completion));
}
void GenericStub::experimental_type::PrepareBidiStreamingCall(
ClientContext* context, const grpc::string& method,
experimental::ClientBidiReactor<ByteBuffer, ByteBuffer>* reactor) {
internal::ClientCallbackReaderWriterFactory<ByteBuffer, ByteBuffer>::Create(
stub_->channel_.get(),
internal::RpcMethod(method.c_str(), internal::RpcMethod::BIDI_STREAMING),
context, reactor);
grpc::ClientContext* context, const grpc::string& method,
grpc::experimental::ClientBidiReactor<grpc::ByteBuffer, grpc::ByteBuffer>*
reactor) {
grpc::internal::ClientCallbackReaderWriterFactory<
grpc::ByteBuffer,
grpc::ByteBuffer>::Create(stub_->channel_.get(),
grpc::internal::RpcMethod(
method.c_str(),
grpc::internal::RpcMethod::BIDI_STREAMING),
context, reactor);
}
} // namespace grpc
} // namespace grpc_impl

@ -23,7 +23,7 @@
#include "src/cpp/ext/proto_server_reflection.h"
namespace grpc {
namespace grpc_impl {
namespace reflection {
ProtoServerReflectionPlugin::ProtoServerReflectionPlugin()
@ -79,4 +79,4 @@ struct StaticProtoReflectionPluginInitializer {
} static_proto_reflection_plugin_initializer;
} // namespace reflection
} // namespace grpc
} // namespace grpc_impl

@ -21,7 +21,7 @@
#include <grpc/grpc.h>
#include <grpc/support/log.h>
namespace grpc {
namespace grpc_impl {
namespace {
class InsecureServerCredentialsImpl final : public ServerCredentials {
public:
@ -29,7 +29,7 @@ class InsecureServerCredentialsImpl final : public ServerCredentials {
return grpc_server_add_insecure_http2_port(server, addr.c_str());
}
void SetAuthMetadataProcessor(
const std::shared_ptr<AuthMetadataProcessor>& processor) override {
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) override {
(void)processor;
GPR_ASSERT(0); // Should not be called on InsecureServerCredentials.
}
@ -41,4 +41,4 @@ std::shared_ptr<ServerCredentials> InsecureServerCredentials() {
new InsecureServerCredentialsImpl());
}
} // namespace grpc
} // namespace grpc_impl

@ -93,21 +93,25 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
status.error_message().c_str());
}
} // namespace grpc
namespace grpc_impl {
int SecureServerCredentials::AddPortToServer(const grpc::string& addr,
grpc_server* server) {
return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
}
void SecureServerCredentials::SetAuthMetadataProcessor(
const std::shared_ptr<AuthMetadataProcessor>& processor) {
auto* wrapper = new AuthMetadataProcessorAyncWrapper(processor);
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) {
auto* wrapper = new grpc::AuthMetadataProcessorAyncWrapper(processor);
grpc_server_credentials_set_auth_metadata_processor(
creds_, {AuthMetadataProcessorAyncWrapper::Process,
AuthMetadataProcessorAyncWrapper::Destroy, wrapper});
creds_, {grpc::AuthMetadataProcessorAyncWrapper::Process,
grpc::AuthMetadataProcessorAyncWrapper::Destroy, wrapper});
}
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options) {
const grpc::SslServerCredentialsOptions& options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
for (auto key_cert_pair = options.pem_key_cert_pairs.begin();
key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) {
@ -147,4 +151,4 @@ std::shared_ptr<ServerCredentials> LocalServerCredentials(
}
} // namespace experimental
} // namespace grpc
} // namespace grpc_impl

@ -27,8 +27,15 @@
#include "src/cpp/server/thread_pool_interface.h"
namespace grpc_impl {
class SecureServerCredentials;
} // namespace grpc_impl
namespace grpc {
typedef ::grpc_impl::SecureServerCredentials SecureServerCredentials;
class AuthMetadataProcessorAyncWrapper final {
public:
static void Destroy(void* wrapper);
@ -49,6 +56,10 @@ class AuthMetadataProcessorAyncWrapper final {
std::shared_ptr<AuthMetadataProcessor> processor_;
};
} // namespace grpc
namespace grpc_impl {
class SecureServerCredentials final : public ServerCredentials {
public:
explicit SecureServerCredentials(grpc_server_credentials* creds)
@ -60,13 +71,13 @@ class SecureServerCredentials final : public ServerCredentials {
int AddPortToServer(const grpc::string& addr, grpc_server* server) override;
void SetAuthMetadataProcessor(
const std::shared_ptr<AuthMetadataProcessor>& processor) override;
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) override;
private:
grpc_server_credentials* creds_;
std::unique_ptr<AuthMetadataProcessorAyncWrapper> processor_;
std::unique_ptr<grpc::AuthMetadataProcessorAyncWrapper> processor_;
};
} // namespace grpc
} // namespace grpc_impl
#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H

@ -16,10 +16,10 @@
*
*/
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/security/server_credentials_impl.h>
namespace grpc {
namespace grpc_impl {
ServerCredentials::~ServerCredentials() {}
} // namespace grpc
} // namespace grpc_impl

@ -32,7 +32,7 @@
s.platform = Gem::Platform::RUBY
s.add_dependency 'google-protobuf', '~> 3.7'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'facter', '~> 2.4'

@ -62,7 +62,7 @@ class CFStreamTest : public ::testing::Test {
CFStreamTest()
: server_host_("grpctest"),
interface_("lo0"),
ipv4_address_("127.0.0.2"),
ipv4_address_("10.0.0.1"),
kRequestMessage_("🖖") {}
void DNSUp() {

@ -24,6 +24,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpcpp/security/server_credentials.h>
#include "test/core/end2end/data/ssl_test_data.h"

@ -936,6 +936,7 @@ include/grpcpp/create_channel_posix_impl.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/generic/generic_stub_impl.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
@ -1006,6 +1007,7 @@ include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \

@ -937,6 +937,7 @@ include/grpcpp/create_channel_posix_impl.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \
include/grpcpp/generic/async_generic_service.h \
include/grpcpp/generic/generic_stub.h \
include/grpcpp/generic/generic_stub_impl.h \
include/grpcpp/grpcpp.h \
include/grpcpp/health_check_service_interface.h \
include/grpcpp/health_check_service_interface_impl.h \
@ -1008,6 +1009,7 @@ include/grpcpp/security/auth_metadata_processor.h \
include/grpcpp/security/auth_metadata_processor_impl.h \
include/grpcpp/security/credentials.h \
include/grpcpp/security/server_credentials.h \
include/grpcpp/security/server_credentials_impl.h \
include/grpcpp/server.h \
include/grpcpp/server_builder.h \
include/grpcpp/server_context.h \

@ -23,7 +23,7 @@ cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321
# Download bazel
temp_dir="$(mktemp -d)"
wget -q https://github.com/bazelbuild/bazel/releases/download/0.22.0/bazel-0.22.0-linux-x86_64 -O "${temp_dir}/bazel"
wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-linux-x86_64 -O "${temp_dir}/bazel"
chmod 755 "${temp_dir}/bazel"
export PATH="${temp_dir}:${PATH}"
# This should show ${temp_dir}/bazel

@ -0,0 +1,369 @@
#Copyright 2019 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.
"""Generate draft and release notes in Markdown from Github PRs.
You'll need a github API token to avoid being rate-limited. See
https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
This script collects PRs using "git log X..Y" from local repo where X and Y are
tags or release branch names of previous and current releases respectively.
Typically, notes are generated before the release branch is labelled so Y is
almost always the name of the release branch. X is the previous release branch
if this is not a patch release. Otherwise, it is the previous release tag.
For example, for release v1.17.0, X will be origin/v1.16.x and for release v1.17.3,
X will be v1.17.2. In both cases Y will be origin/v1.17.x.
"""
from collections import defaultdict
import base64
import json
content_header = """Draft Release Notes For {version}
--
Final release notes will be generated from the PR titles that have *"release notes:yes"* label. If you have any additional notes please add them below. These will be appended to auto generated release notes. Previous releases notes are [here](https://github.com/grpc/grpc/releases).
**Also, look at the PRs listed below against your name.** Please apply the missing labels and make necessary corrections (like fixing the title) to the PR in Github. Final release notes will be generated just before the release on {date}.
Add additional notes not in PRs
--
Core
-
C++
-
C#
-
Objective-C
-
PHP
-
Python
-
Ruby
-
"""
rl_header = """This is the {version} release ([{name}](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md)) of gRPC Core.
Please see the notes for the previous releases here: https://github.com/grpc/grpc/releases. Please consult https://grpc.io/ for all information regarding this product.
This release contains refinements, improvements, and bug fixes, with highlights listed below.
"""
HTML_URL = "https://github.com/grpc/grpc/pull/"
API_URL = 'https://api.github.com/repos/grpc/grpc/pulls/'
def get_commit_log(prevRelLabel, relBranch):
"""Return the output of 'git log --pretty=online --merges prevRelLabel..relBranch' """
import subprocess
print("Running git log --pretty=oneline --merges " + prevRelLabel + ".." +
relBranch)
return subprocess.check_output([
"git", "log", "--pretty=oneline", "--merges",
"%s..%s" % (prevRelLabel, relBranch)
])
def get_pr_data(pr_num):
"""Get the PR data from github. Return 'error' on exception"""
try:
from urllib2 import Request, urlopen, HTTPError
except ImportError:
import urllib
from urllib.request import Request, urlopen, HTTPError
url = API_URL + pr_num
req = Request(url)
req.add_header('Authorization', 'token %s' % TOKEN)
try:
f = urlopen(req)
response = json.loads(f.read().decode('utf-8'))
#print(response)
except HTTPError as e:
response = json.loads(e.fp.read().decode('utf-8'))
if 'message' in response:
print(response['message'])
response = "error"
return response
def get_pr_titles(gitLogs):
import re
error_count = 0
match = b"Merge pull request #(\d+)"
prlist = re.findall(match, gitLogs, re.MULTILINE)
print("\nPRs matching 'Merge pull request #<num>':")
print(prlist)
print("\n")
langs_pr = defaultdict(list)
for pr_num in prlist:
pr_num = str(pr_num)
print("---------- getting data for PR " + pr_num)
pr = get_pr_data(pr_num)
if pr == "error":
print("\n***ERROR*** Error in getting data for PR " + pr_num + "\n")
error_count += 1
continue
rl_no_found = False
rl_yes_found = False
lang_found = False
for label in pr['labels']:
if label['name'] == 'release notes: yes':
rl_yes_found = True
elif label['name'] == 'release notes: no':
rl_no_found = True
elif label['name'].startswith('lang/'):
lang_found = True
lang = label['name'].split('/')[1].lower()
#lang = lang[0].upper() + lang[1:]
body = pr["title"]
if not body.endswith("."):
body = body + "."
if not pr["merged_by"]:
print("\n***ERROR***: No merge_by found for PR " + pr_num + "\n")
error_count += 1
continue
prline = "- " + body + " ([#" + pr_num + "](" + HTML_URL + pr_num + "))"
detail = "- " + pr["merged_by"]["login"] + "@ " + prline
prline = prline.encode('ascii', 'ignore')
detail = detail.encode('ascii', 'ignore')
print(detail)
#if no RL label
if not rl_no_found and not rl_yes_found:
print("Release notes label missing for " + pr_num)
langs_pr["nolabel"].append(detail)
elif rl_yes_found and not lang_found:
print("Lang label missing for " + pr_num)
langs_pr["nolang"].append(detail)
elif rl_no_found:
print("'Release notes:no' found for " + pr_num)
langs_pr["notinrel"].append(detail)
elif rl_yes_found:
print("'Release notes:yes' found for " + pr_num + " with lang " +
lang)
langs_pr["inrel"].append(detail)
langs_pr[lang].append(prline)
return langs_pr, error_count
def write_draft(langs_pr, file, version, date):
file.write(content_header.format(version=version, date=date))
file.write("PRs with missing release notes label - please fix in Github\n")
file.write("---\n")
file.write("\n")
if langs_pr["nolabel"]:
langs_pr["nolabel"].sort()
file.write("\n".join(langs_pr["nolabel"]))
else:
file.write("- None")
file.write("\n")
file.write("\n")
file.write("PRs with missing lang label - please fix in Github\n")
file.write("---\n")
file.write("\n")
if langs_pr["nolang"]:
langs_pr["nolang"].sort()
file.write("\n".join(langs_pr["nolang"]))
else:
file.write("- None")
file.write("\n")
file.write("\n")
file.write(
"PRs going into release notes - please check title and fix in Github. Do not edit here.\n"
)
file.write("---\n")
file.write("\n")
if langs_pr["inrel"]:
langs_pr["inrel"].sort()
file.write("\n".join(langs_pr["inrel"]))
else:
file.write("- None")
file.write("\n")
file.write("\n")
file.write("PRs not going into release notes\n")
file.write("---\n")
file.write("\n")
if langs_pr["notinrel"]:
langs_pr["notinrel"].sort()
file.write("\n".join(langs_pr["notinrel"]))
else:
file.write("- None")
file.write("\n")
file.write("\n")
def write_rel_notes(langs_pr, file, version, name):
file.write(rl_header.format(version=version, name=name))
if langs_pr["core"]:
file.write("Core\n---\n\n")
file.write("\n".join(langs_pr["core"]))
file.write("\n")
file.write("\n")
if langs_pr["c++"]:
file.write("C++\n---\n\n")
file.write("\n".join(langs_pr["c++"]))
file.write("\n")
file.write("\n")
if langs_pr["c#"]:
file.write("C#\n---\n\n")
file.write("\n".join(langs_pr["c#"]))
file.write("\n")
file.write("\n")
if langs_pr["go"]:
file.write("Go\n---\n\n")
file.write("\n".join(langs_pr["go"]))
file.write("\n")
file.write("\n")
if langs_pr["Java"]:
file.write("Java\n---\n\n")
file.write("\n".join(langs_pr["Java"]))
file.write("\n")
file.write("\n")
if langs_pr["node"]:
file.write("Node\n---\n\n")
file.write("\n".join(langs_pr["node"]))
file.write("\n")
file.write("\n")
if langs_pr["objc"]:
file.write("Objective-C\n---\n\n")
file.write("\n".join(langs_pr["objc"]))
file.write("\n")
file.write("\n")
if langs_pr["php"]:
file.write("PHP\n---\n\n")
file.write("\n".join(langs_pr["php"]))
file.write("\n")
file.write("\n")
if langs_pr["python"]:
file.write("Python\n---\n\n")
file.write("\n".join(langs_pr["python"]))
file.write("\n")
file.write("\n")
if langs_pr["ruby"]:
file.write("Ruby\n---\n\n")
file.write("\n".join(langs_pr["ruby"]))
file.write("\n")
file.write("\n")
if langs_pr["other"]:
file.write("Other\n---\n\n")
file.write("\n".join(langs_pr["other"]))
file.write("\n")
file.write("\n")
def build_args_parser():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'release_version', type=str, help='New release version e.g. 1.14.0')
parser.add_argument(
'release_name', type=str, help='New release name e.g. gladiolus')
parser.add_argument(
'release_date', type=str, help='Release date e.g. 7/30/18')
parser.add_argument(
'previous_release_label',
type=str,
help='Previous release branch/tag e.g. v1.13.x')
parser.add_argument(
'release_branch',
type=str,
help='Current release branch e.g. origin/v1.14.x')
parser.add_argument(
'draft_filename', type=str, help='Name of the draft file e.g. draft.md')
parser.add_argument(
'release_notes_filename',
type=str,
help='Name of the release notes file e.g. relnotes.md')
parser.add_argument(
'--token',
type=str,
default='',
help='GitHub API token to avoid being rate limited')
return parser
def main():
import os
global TOKEN
parser = build_args_parser()
args = parser.parse_args()
version, name, date = args.release_version, args.release_name, args.release_date
start, end = args.previous_release_label, args.release_branch
TOKEN = args.token
if TOKEN == '':
try:
TOKEN = os.environ["GITHUB_TOKEN"]
except:
pass
if TOKEN == '':
print(
"Error: Github API token required. Either include param --token=<your github token> or set environment variable GITHUB_TOKEN to your github token"
)
return
langs_pr, error_count = get_pr_titles(get_commit_log(start, end))
draft_file, rel_file = args.draft_filename, args.release_notes_filename
filename = os.path.abspath(draft_file)
if os.path.exists(filename):
file = open(filename, 'r+')
else:
file = open(filename, 'w')
file.seek(0)
write_draft(langs_pr, file, version, date)
file.truncate()
file.close()
print("\nDraft notes written to " + filename)
filename = os.path.abspath(rel_file)
if os.path.exists(filename):
file = open(filename, 'r+')
else:
file = open(filename, 'w')
file.seek(0)
write_rel_notes(langs_pr, file, version, name)
file.truncate()
file.close()
print("\nRelease notes written to " + filename)
if error_count > 0:
print("\n\n*** Errors were encountered. See log. *********\n")
if __name__ == "__main__":
main()

@ -6652,6 +6652,7 @@
"headers": [
"include/grpc++/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin_impl.h",
"src/cpp/ext/proto_server_reflection.h"
],
"is_filegroup": false,
@ -6660,6 +6661,7 @@
"src": [
"include/grpc++/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin.h",
"include/grpcpp/ext/proto_server_reflection_plugin_impl.h",
"src/cpp/ext/proto_server_reflection.cc",
"src/cpp/ext/proto_server_reflection.h",
"src/cpp/ext/proto_server_reflection_plugin.cc"
@ -10099,6 +10101,7 @@
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/generic/generic_stub_impl.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
@ -10124,6 +10127,7 @@
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
"include/grpcpp/server_context.h",
@ -10216,6 +10220,7 @@
"include/grpcpp/ext/health_check_service_server_builder_option.h",
"include/grpcpp/generic/async_generic_service.h",
"include/grpcpp/generic/generic_stub.h",
"include/grpcpp/generic/generic_stub_impl.h",
"include/grpcpp/grpcpp.h",
"include/grpcpp/health_check_service_interface.h",
"include/grpcpp/health_check_service_interface_impl.h",
@ -10241,6 +10246,7 @@
"include/grpcpp/security/auth_metadata_processor_impl.h",
"include/grpcpp/security/credentials.h",
"include/grpcpp/security/server_credentials.h",
"include/grpcpp/security/server_credentials_impl.h",
"include/grpcpp/server.h",
"include/grpcpp/server_builder.h",
"include/grpcpp/server_context.h",

Loading…
Cancel
Save