mirror of https://github.com/grpc/grpc.git
commit
f01997b377
246 changed files with 5077 additions and 1501 deletions
@ -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.") |
||||
|
@ -0,0 +1,56 @@ |
||||
# 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. |
||||
|
||||
load("@grpc_python_dependencies//:requirements.bzl", "requirement") |
||||
|
||||
py_library( |
||||
name = "client", |
||||
testonly = 1, |
||||
srcs = ["client.py"], |
||||
deps = [ |
||||
"//src/python/grpcio/grpc:grpcio", |
||||
"//src/python/grpcio_status/grpc_status:grpc_status", |
||||
"//examples:py_helloworld", |
||||
requirement('googleapis-common-protos'), |
||||
], |
||||
) |
||||
|
||||
py_library( |
||||
name = "server", |
||||
testonly = 1, |
||||
srcs = ["server.py"], |
||||
deps = [ |
||||
"//src/python/grpcio/grpc:grpcio", |
||||
"//src/python/grpcio_status/grpc_status:grpc_status", |
||||
"//examples:py_helloworld", |
||||
] + select({ |
||||
"//conditions:default": [requirement("futures")], |
||||
"//:python3": [], |
||||
}), |
||||
) |
||||
|
||||
py_test( |
||||
name = "test/_error_handling_example_test", |
||||
srcs = ["test/_error_handling_example_test.py"], |
||||
deps = [ |
||||
":client", |
||||
":server", |
||||
"//src/python/grpcio_tests/tests:bazel_namespace_package_hack", |
||||
], |
||||
size = "small", |
||||
imports = [ |
||||
"../../../src/python/grpcio_status", |
||||
"../../../src/python/grpcio_tests", |
||||
], |
||||
) |
@ -0,0 +1,107 @@ |
||||
# gRPC Python Error Handling Example |
||||
|
||||
The goal of this example is sending error status from server that is more complicated than a code and detail string. |
||||
|
||||
The definition for an RPC method in proto files contains request message and response message. There are many error states that can be shared across RPC methods (e.g. stack trace, insufficient quota). Using a different path to handle error will make the code more maintainable. |
||||
|
||||
Ideally, the final status of an RPC should be described in the trailing headers of HTTP2, and gRPC Python provides helper functions in `grpcio-status` package to assist the packing and unpacking of error status. |
||||
|
||||
|
||||
### Requirement |
||||
``` |
||||
grpcio>=1.18.0 |
||||
grpcio-status>=1.18.0 |
||||
googleapis-common-protos>=1.5.5 |
||||
``` |
||||
|
||||
|
||||
### Error Detail Proto |
||||
|
||||
You may provide any custom proto message as error detail in your implementation. Here are protos are defined by Google Cloud Library Team: |
||||
|
||||
* [code.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/code.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/code.proto)) contains definition of RPC error codes. |
||||
* [error_details.proto]([https://github.com/googleapis/api-common-protos/blob/master/google/rpc/error_details.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/error_details.proto)) contains definitions of common error details. |
||||
|
||||
|
||||
### Definition of Status Proto |
||||
|
||||
Here is the definition of Status proto. For full text, please see [status.proto](https://github.com/googleapis/api-common-protos/blob/87185dfffad4afa5a33a8c153f0e1ea53b4f85dc/google/rpc/status.proto). |
||||
|
||||
```proto |
||||
// The `Status` type defines a logical error model that is suitable for different |
||||
// programming environments, including REST APIs and RPC APIs. It is used by |
||||
// [gRPC](https://github.com/grpc). The error model is designed to be: |
||||
// |
||||
// - Simple to use and understand for most users |
||||
// - Flexible enough to meet unexpected needs |
||||
// |
||||
// # Overview |
||||
// |
||||
// The `Status` message contains three pieces of data: error code, error message, |
||||
// and error details. The error code should be an enum value of |
||||
// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The |
||||
// error message should be a developer-facing English message that helps |
||||
// developers *understand* and *resolve* the error. If a localized user-facing |
||||
// error message is needed, put the localized message in the error details or |
||||
// localize it in the client. The optional error details may contain arbitrary |
||||
// information about the error. There is a predefined set of error detail types |
||||
// in the package `google.rpc` that can be used for common error conditions. |
||||
// |
||||
// # Language mapping |
||||
// |
||||
// The `Status` message is the logical representation of the error model, but it |
||||
// is not necessarily the actual wire format. When the `Status` message is |
||||
// exposed in different client libraries and different wire protocols, it can be |
||||
// mapped differently. For example, it will likely be mapped to some exceptions |
||||
// in Java, but more likely mapped to some error codes in C. |
||||
// |
||||
// # Other uses |
||||
// |
||||
// The error model and the `Status` message can be used in a variety of |
||||
// environments, either with or without APIs, to provide a |
||||
// consistent developer experience across different environments. |
||||
// |
||||
// Example uses of this error model include: |
||||
// |
||||
// - Partial errors. If a service needs to return partial errors to the client, |
||||
// it may embed the `Status` in the normal response to indicate the partial |
||||
// errors. |
||||
// |
||||
// - Workflow errors. A typical workflow has multiple steps. Each step may |
||||
// have a `Status` message for error reporting. |
||||
// |
||||
// - Batch operations. If a client uses batch request and batch response, the |
||||
// `Status` message should be used directly inside batch response, one for |
||||
// each error sub-response. |
||||
// |
||||
// - Asynchronous operations. If an API call embeds asynchronous operation |
||||
// results in its response, the status of those operations should be |
||||
// represented directly using the `Status` message. |
||||
// |
||||
// - Logging. If some API errors are stored in logs, the message `Status` could |
||||
// be used directly after any stripping needed for security/privacy reasons. |
||||
message Status { |
||||
// The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. |
||||
int32 code = 1; |
||||
|
||||
// A developer-facing error message, which should be in English. Any |
||||
// user-facing error message should be localized and sent in the |
||||
// [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. |
||||
string message = 2; |
||||
|
||||
// A list of messages that carry the error details. There is a common set of |
||||
// message types for APIs to use. |
||||
repeated google.protobuf.Any details = 3; |
||||
} |
||||
``` |
||||
|
||||
|
||||
### Usage of Well-Known-Proto `Any` |
||||
|
||||
Please check [ProtoBuf Document: Any](https://developers.google.com/protocol-buffers/docs/reference/python-generated#any) |
||||
|
||||
```Python |
||||
any_message.Pack(message) |
||||
any_message.Unpack(message) |
||||
assert any_message.Is(message.DESCRIPTOR) |
||||
``` |
@ -0,0 +1,56 @@ |
||||
# 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. |
||||
"""This example handles rich error status in client-side.""" |
||||
|
||||
from __future__ import print_function |
||||
import logging |
||||
|
||||
import grpc |
||||
from grpc_status import rpc_status |
||||
from google.rpc import error_details_pb2 |
||||
|
||||
from examples.protos import helloworld_pb2 |
||||
from examples.protos import helloworld_pb2_grpc |
||||
|
||||
_LOGGER = logging.getLogger(__name__) |
||||
|
||||
|
||||
def process(stub): |
||||
try: |
||||
response = stub.SayHello(helloworld_pb2.HelloRequest(name='Alice')) |
||||
_LOGGER.info('Call success: %s', response.message) |
||||
except grpc.RpcError as rpc_error: |
||||
_LOGGER.error('Call failure: %s', rpc_error) |
||||
status = rpc_status.from_call(rpc_error) |
||||
for detail in status.details: |
||||
if detail.Is(error_details_pb2.QuotaFailure.DESCRIPTOR): |
||||
info = error_details_pb2.QuotaFailure() |
||||
detail.Unpack(info) |
||||
_LOGGER.error('Quota failure: %s', info) |
||||
else: |
||||
raise RuntimeError('Unexpected failure: %s' % detail) |
||||
|
||||
|
||||
def main(): |
||||
# NOTE(gRPC Python Team): .close() is possible on a channel and should be |
||||
# used in circumstances in which the with statement does not fit the needs |
||||
# of the code. |
||||
with grpc.insecure_channel('localhost:50051') as channel: |
||||
stub = helloworld_pb2_grpc.GreeterStub(channel) |
||||
process(stub) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
logging.basicConfig() |
||||
main() |
@ -0,0 +1,90 @@ |
||||
# 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. |
||||
"""This example sends out rich error status from server-side.""" |
||||
|
||||
from concurrent import futures |
||||
import time |
||||
import logging |
||||
import threading |
||||
|
||||
import grpc |
||||
from grpc_status import rpc_status |
||||
|
||||
from google.protobuf import any_pb2 |
||||
from google.rpc import code_pb2, status_pb2, error_details_pb2 |
||||
|
||||
from examples.protos import helloworld_pb2 |
||||
from examples.protos import helloworld_pb2_grpc |
||||
|
||||
_ONE_DAY_IN_SECONDS = 60 * 60 * 24 |
||||
|
||||
|
||||
def create_greet_limit_exceed_error_status(name): |
||||
detail = any_pb2.Any() |
||||
detail.Pack( |
||||
error_details_pb2.QuotaFailure( |
||||
violations=[ |
||||
error_details_pb2.QuotaFailure.Violation( |
||||
subject="name: %s" % name, |
||||
description="Limit one greeting per person", |
||||
) |
||||
],)) |
||||
return status_pb2.Status( |
||||
code=code_pb2.RESOURCE_EXHAUSTED, |
||||
message='Request limit exceeded.', |
||||
details=[detail], |
||||
) |
||||
|
||||
|
||||
class LimitedGreeter(helloworld_pb2_grpc.GreeterServicer): |
||||
|
||||
def __init__(self): |
||||
self._lock = threading.RLock() |
||||
self._greeted = set() |
||||
|
||||
def SayHello(self, request, context): |
||||
with self._lock: |
||||
if request.name in self._greeted: |
||||
rich_status = create_greet_limit_exceed_error_status( |
||||
request.name) |
||||
context.abort_with_status(rpc_status.to_status(rich_status)) |
||||
else: |
||||
self._greeted.add(request.name) |
||||
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) |
||||
|
||||
|
||||
def create_server(server_address): |
||||
server = grpc.server(futures.ThreadPoolExecutor()) |
||||
helloworld_pb2_grpc.add_GreeterServicer_to_server(LimitedGreeter(), server) |
||||
port = server.add_insecure_port(server_address) |
||||
return server, port |
||||
|
||||
|
||||
def serve(server): |
||||
server.start() |
||||
try: |
||||
while True: |
||||
time.sleep(_ONE_DAY_IN_SECONDS) |
||||
except KeyboardInterrupt: |
||||
server.stop(None) |
||||
|
||||
|
||||
def main(): |
||||
server, unused_port = create_server('[::]:50051') |
||||
serve(server) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
logging.basicConfig() |
||||
main() |
@ -0,0 +1,54 @@ |
||||
# 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. |
||||
"""Tests of the error handling example.""" |
||||
|
||||
# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details |
||||
# please refer to comments in the "bazel_namespace_package_hack" module. |
||||
try: |
||||
from tests import bazel_namespace_package_hack |
||||
bazel_namespace_package_hack.sys_path_to_site_dir_hack() |
||||
except ImportError: |
||||
pass |
||||
|
||||
import unittest |
||||
import logging |
||||
|
||||
import grpc |
||||
|
||||
from examples.protos import helloworld_pb2_grpc |
||||
from examples.python.errors import client as error_handling_client |
||||
from examples.python.errors import server as error_handling_server |
||||
|
||||
|
||||
class ErrorHandlingExampleTest(unittest.TestCase): |
||||
|
||||
def setUp(self): |
||||
self._server, port = error_handling_server.create_server('[::]:0') |
||||
self._server.start() |
||||
self._channel = grpc.insecure_channel('localhost:%d' % port) |
||||
|
||||
def tearDown(self): |
||||
self._channel.close() |
||||
self._server.stop(None) |
||||
|
||||
def test_error_handling_example(self): |
||||
stub = helloworld_pb2_grpc.GreeterStub(self._channel) |
||||
error_handling_client.process(stub) |
||||
error_handling_client.process(stub) |
||||
# No unhandled exception raised, test passed! |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
logging.basicConfig() |
||||
unittest.main(verbosity=2) |
@ -0,0 +1,79 @@ |
||||
/*
|
||||
* |
||||
* 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_CREATE_CHANNEL_IMPL_H |
||||
#define GRPCPP_CREATE_CHANNEL_IMPL_H |
||||
|
||||
#include <memory> |
||||
|
||||
#include <grpcpp/channel.h> |
||||
#include <grpcpp/impl/codegen/client_interceptor.h> |
||||
#include <grpcpp/security/credentials.h> |
||||
#include <grpcpp/support/channel_arguments.h> |
||||
#include <grpcpp/support/config.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// Create a new \a Channel pointing to \a target.
|
||||
///
|
||||
/// \param target The URI of the endpoint to connect to.
|
||||
/// \param creds Credentials to use for the created channel. If it does not
|
||||
/// hold an object or is invalid, a lame channel (one on which all operations
|
||||
/// fail) is returned.
|
||||
std::shared_ptr<grpc::Channel> CreateChannel( |
||||
const grpc::string& target, |
||||
const std::shared_ptr<grpc::ChannelCredentials>& creds); |
||||
|
||||
/// Create a new \em custom \a Channel pointing to \a target.
|
||||
///
|
||||
/// \warning For advanced use and testing ONLY. Override default channel
|
||||
/// arguments only if necessary.
|
||||
///
|
||||
/// \param target The URI of the endpoint to connect to.
|
||||
/// \param creds Credentials to use for the created channel. If it does not
|
||||
/// hold an object or is invalid, a lame channel (one on which all operations
|
||||
/// fail) is returned.
|
||||
/// \param args Options for channel creation.
|
||||
std::shared_ptr<grpc::Channel> CreateCustomChannel( |
||||
const grpc::string& target, |
||||
const std::shared_ptr<grpc::ChannelCredentials>& creds, |
||||
const grpc::ChannelArguments& args); |
||||
|
||||
namespace experimental { |
||||
/// Create a new \em custom \a Channel pointing to \a target with \a
|
||||
/// interceptors being invoked per call.
|
||||
///
|
||||
/// \warning For advanced use and testing ONLY. Override default channel
|
||||
/// arguments only if necessary.
|
||||
///
|
||||
/// \param target The URI of the endpoint to connect to.
|
||||
/// \param creds Credentials to use for the created channel. If it does not
|
||||
/// hold an object or is invalid, a lame channel (one on which all operations
|
||||
/// fail) is returned.
|
||||
/// \param args Options for channel creation.
|
||||
std::shared_ptr<grpc::Channel> CreateCustomChannelWithInterceptors( |
||||
const grpc::string& target, |
||||
const std::shared_ptr<grpc::ChannelCredentials>& creds, |
||||
const grpc::ChannelArguments& args, |
||||
std::vector< |
||||
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>> |
||||
interceptor_creators); |
||||
} // namespace experimental
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_CREATE_CHANNEL_IMPL_H
|
@ -0,0 +1,70 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H |
||||
#define GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H |
||||
|
||||
#include <memory> |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
#include <grpcpp/channel.h> |
||||
#include <grpcpp/support/channel_arguments.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD |
||||
|
||||
/// Create a new \a Channel communicating over the given file descriptor.
|
||||
///
|
||||
/// \param target The name of the target.
|
||||
/// \param fd The file descriptor representing a socket.
|
||||
std::shared_ptr<grpc::Channel> CreateInsecureChannelFromFd( |
||||
const grpc::string& target, int fd); |
||||
|
||||
/// Create a new \a Channel communicating over given file descriptor with custom
|
||||
/// channel arguments.
|
||||
///
|
||||
/// \param target The name of the target.
|
||||
/// \param fd The file descriptor representing a socket.
|
||||
/// \param args Options for channel creation.
|
||||
std::shared_ptr<grpc::Channel> CreateCustomInsecureChannelFromFd( |
||||
const grpc::string& target, int fd, const grpc::ChannelArguments& args); |
||||
|
||||
namespace experimental { |
||||
|
||||
/// Create a new \a Channel communicating over given file descriptor with custom
|
||||
/// channel arguments.
|
||||
///
|
||||
/// \param target The name of the target.
|
||||
/// \param fd The file descriptor representing a socket.
|
||||
/// \param args Options for channel creation.
|
||||
/// \param interceptor_creators Vector of interceptor factory objects.
|
||||
std::shared_ptr<grpc::Channel> |
||||
CreateCustomInsecureChannelWithInterceptorsFromFd( |
||||
const grpc::string& target, int fd, const grpc::ChannelArguments& args, |
||||
std::unique_ptr<std::vector< |
||||
std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>> |
||||
interceptor_creators); |
||||
|
||||
} // namespace experimental
|
||||
|
||||
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
|
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_CREATE_CHANNEL_POSIX_IMPL_H
|
@ -0,0 +1,41 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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_CHANNELZ_SERVICE_PLUGIN_IMPL_H |
||||
#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpcpp/impl/server_builder_plugin.h> |
||||
#include <grpcpp/impl/server_initializer.h> |
||||
#include <grpcpp/support/config.h> |
||||
|
||||
namespace grpc_impl { |
||||
namespace channelz { |
||||
namespace experimental { |
||||
|
||||
/// Add channelz server plugin to \a ServerBuilder. This function should
|
||||
/// be called at static initialization time. This service is experimental
|
||||
/// for now. Track progress in https://github.com/grpc/grpc/issues/15988.
|
||||
void InitChannelzService(); |
||||
|
||||
} // namespace experimental
|
||||
} // namespace channelz
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_IMPL_H
|
@ -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
|
@ -0,0 +1,54 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 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_SERVER_LOAD_REPORTING_IMPL_H |
||||
#define GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/load_reporting.h> |
||||
#include <grpcpp/impl/codegen/config.h> |
||||
#include <grpcpp/impl/codegen/server_context.h> |
||||
#include <grpcpp/impl/server_builder_option.h> |
||||
|
||||
namespace grpc_impl { |
||||
namespace load_reporter { |
||||
namespace experimental { |
||||
|
||||
// The ServerBuilderOption to enable server-side load reporting feature. To
|
||||
// enable the feature, please make sure the binary builds with the
|
||||
// grpcpp_server_load_reporting library and set this option in the
|
||||
// ServerBuilder.
|
||||
class LoadReportingServiceServerBuilderOption |
||||
: public grpc::ServerBuilderOption { |
||||
public: |
||||
void UpdateArguments(::grpc::ChannelArguments* args) override; |
||||
void UpdatePlugins(std::vector<std::unique_ptr<::grpc::ServerBuilderPlugin>>* |
||||
plugins) override; |
||||
}; |
||||
|
||||
// Adds the load reporting cost with \a cost_name and \a cost_value in the
|
||||
// trailing metadata of the server context.
|
||||
void AddLoadReportingCost(grpc::ServerContext* ctx, |
||||
const grpc::string& cost_name, double cost_value); |
||||
|
||||
} // namespace experimental
|
||||
} // namespace load_reporter
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_EXT_SERVER_LOAD_REPORTING_IMPL_H
|
@ -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
|
@ -0,0 +1,55 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H |
||||
#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H |
||||
|
||||
#include <grpcpp/support/config.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// The gRPC server uses this interface to expose the health checking service
|
||||
/// without depending on protobuf.
|
||||
class HealthCheckServiceInterface { |
||||
public: |
||||
virtual ~HealthCheckServiceInterface() {} |
||||
|
||||
/// Set or change the serving status of the given \a service_name.
|
||||
virtual void SetServingStatus(const grpc::string& service_name, |
||||
bool serving) = 0; |
||||
/// Apply to all registered service names.
|
||||
virtual void SetServingStatus(bool serving) = 0; |
||||
|
||||
/// Set all registered service names to not serving and prevent future
|
||||
/// state changes.
|
||||
virtual void Shutdown() {} |
||||
}; |
||||
|
||||
/// Enable/disable the default health checking service. This applies to all C++
|
||||
/// servers created afterwards. For each server, user can override the default
|
||||
/// with a HealthCheckServiceServerBuilderOption.
|
||||
/// NOT thread safe.
|
||||
void EnableDefaultHealthCheckService(bool enable); |
||||
|
||||
/// Returns whether the default health checking service is enabled.
|
||||
/// NOT thread safe.
|
||||
bool DefaultHealthCheckServiceEnabled(); |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_IMPL_H
|
@ -0,0 +1,43 @@ |
||||
/*
|
||||
* |
||||
* 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_IMPL_SERVER_BUILDER_OPTION_IMPL_H |
||||
#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H |
||||
|
||||
#include <map> |
||||
#include <memory> |
||||
|
||||
#include <grpcpp/impl/server_builder_plugin.h> |
||||
#include <grpcpp/support/channel_arguments.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// Interface to pass an option to a \a ServerBuilder.
|
||||
class ServerBuilderOption { |
||||
public: |
||||
virtual ~ServerBuilderOption() {} |
||||
/// Alter the \a ChannelArguments used to create the gRPC server.
|
||||
virtual void UpdateArguments(grpc::ChannelArguments* args) = 0; |
||||
/// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
|
||||
virtual void UpdatePlugins( |
||||
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>>* plugins) = 0; |
||||
}; |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_IMPL_SERVER_BUILDER_OPTION_IMPL_H
|
@ -0,0 +1,57 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H |
||||
#define GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H |
||||
|
||||
#include <memory> |
||||
#include <vector> |
||||
|
||||
#include <grpcpp/server.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
class Server; |
||||
class Service; |
||||
} // namespace grpc
|
||||
namespace grpc_impl { |
||||
|
||||
class ServerInitializer { |
||||
public: |
||||
ServerInitializer(grpc::Server* server) : server_(server) {} |
||||
|
||||
bool RegisterService(std::shared_ptr<grpc::Service> service) { |
||||
if (!server_->RegisterService(nullptr, service.get())) { |
||||
return false; |
||||
} |
||||
default_services_.push_back(service); |
||||
return true; |
||||
} |
||||
|
||||
const std::vector<grpc::string>* GetServiceList() { |
||||
return &server_->services_; |
||||
} |
||||
|
||||
private: |
||||
grpc::Server* server_; |
||||
std::vector<std::shared_ptr<grpc::Service> > default_services_; |
||||
}; |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_IMPL_SERVER_INITIALIZER_IMPL_H
|
@ -0,0 +1,51 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_OPENCENSUS_IMPL_H |
||||
#define GRPCPP_OPENCENSUS_IMPL_H |
||||
|
||||
#include "opencensus/trace/span.h" |
||||
|
||||
namespace grpc { |
||||
|
||||
class ServerContext; |
||||
} |
||||
namespace grpc_impl { |
||||
// These symbols in this file will not be included in the binary unless
|
||||
// grpc_opencensus_plugin build target was added as a dependency. At the moment
|
||||
// it is only setup to be built with Bazel.
|
||||
|
||||
// Registers the OpenCensus plugin with gRPC, so that it will be used for future
|
||||
// RPCs. This must be called before any views are created.
|
||||
void RegisterOpenCensusPlugin(); |
||||
|
||||
// RPC stats definitions, defined by
|
||||
// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md
|
||||
|
||||
// Registers the cumulative gRPC views so that they will be exported by any
|
||||
// registered stats exporter. For on-task stats, construct a View using the
|
||||
// ViewDescriptors below.
|
||||
void RegisterOpenCensusViewsForExport(); |
||||
|
||||
// Returns the tracing Span for the current RPC.
|
||||
::opencensus::trace::Span GetSpanFromServerContext( |
||||
grpc::ServerContext* context); |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_OPENCENSUS_IMPL_H
|
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_RESOURCE_QUOTA_IMPL_H |
||||
#define GRPCPP_RESOURCE_QUOTA_IMPL_H |
||||
|
||||
struct grpc_resource_quota; |
||||
|
||||
#include <grpcpp/impl/codegen/config.h> |
||||
#include <grpcpp/impl/codegen/grpc_library.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// ResourceQuota represents a bound on memory and thread usage by the gRPC
|
||||
/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder),
|
||||
/// or a client channel (via \a ChannelArguments).
|
||||
/// gRPC will attempt to keep memory and threads used by all attached entities
|
||||
/// below the ResourceQuota bound.
|
||||
class ResourceQuota final : private ::grpc::GrpcLibraryCodegen { |
||||
public: |
||||
/// \param name - a unique name for this ResourceQuota.
|
||||
explicit ResourceQuota(const grpc::string& name); |
||||
ResourceQuota(); |
||||
~ResourceQuota(); |
||||
|
||||
/// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
|
||||
/// than the current size of the pool, memory usage will be monotonically
|
||||
/// decreased until it falls under \a new_size.
|
||||
/// No time bound is given for this to occur however.
|
||||
ResourceQuota& Resize(size_t new_size); |
||||
|
||||
/// Set the max number of threads that can be allocated from this
|
||||
/// ResourceQuota object.
|
||||
///
|
||||
/// If the new_max_threads value is smaller than the current value, no new
|
||||
/// threads are allocated until the number of active threads fall below
|
||||
/// new_max_threads. There is no time bound on when this may happen i.e none
|
||||
/// of the current threads are forcefully destroyed and all threads run their
|
||||
/// normal course.
|
||||
ResourceQuota& SetMaxThreads(int new_max_threads); |
||||
|
||||
grpc_resource_quota* c_resource_quota() const { return impl_; } |
||||
|
||||
private: |
||||
ResourceQuota(const ResourceQuota& rhs); |
||||
ResourceQuota& operator=(const ResourceQuota& rhs); |
||||
|
||||
grpc_resource_quota* const impl_; |
||||
}; |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_RESOURCE_QUOTA_IMPL_H
|
@ -0,0 +1,61 @@ |
||||
/*
|
||||
* |
||||
* 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_AUTH_METADATA_PROCESSOR_IMPL_H |
||||
#define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H |
||||
|
||||
#include <map> |
||||
|
||||
#include <grpcpp/security/auth_context.h> |
||||
#include <grpcpp/support/status.h> |
||||
#include <grpcpp/support/string_ref.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// Interface allowing custom server-side authorization based on credentials
|
||||
/// encoded in metadata. Objects of this type can be passed to
|
||||
/// \a ServerCredentials::SetAuthMetadataProcessor().
|
||||
class AuthMetadataProcessor { |
||||
public: |
||||
typedef std::multimap<grpc::string_ref, grpc::string_ref> InputMetadata; |
||||
typedef std::multimap<grpc::string, grpc::string> OutputMetadata; |
||||
|
||||
virtual ~AuthMetadataProcessor() {} |
||||
|
||||
/// If this method returns true, the \a Process function will be scheduled in
|
||||
/// a different thread from the one processing the call.
|
||||
virtual bool IsBlocking() const { return true; } |
||||
|
||||
/// context is read/write: it contains the properties of the channel peer and
|
||||
/// it is the job of the Process method to augment it with properties derived
|
||||
/// from the passed-in auth_metadata.
|
||||
/// consumed_auth_metadata needs to be filled with metadata that has been
|
||||
/// consumed by the processor and will be removed from the call.
|
||||
/// response_metadata is the metadata that will be sent as part of the
|
||||
/// response.
|
||||
/// If the return value is not Status::OK, the rpc call will be aborted with
|
||||
/// the error code and error message sent back to the client.
|
||||
virtual grpc::Status Process(const InputMetadata& auth_metadata, |
||||
grpc::AuthContext* context, |
||||
OutputMetadata* consumed_auth_metadata, |
||||
OutputMetadata* response_metadata) = 0; |
||||
}; |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_IMPL_H
|
@ -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 { |
||||
|
||||
class Server; |
||||
struct SslServerCredentialsOptions; |
||||
} // namespace grpc
|
||||
namespace grpc_impl { |
||||
|
||||
/// 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::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
|
@ -0,0 +1,42 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPCPP_SERVER_POSIX_IMPL_H |
||||
#define GRPCPP_SERVER_POSIX_IMPL_H |
||||
|
||||
#include <memory> |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
#include <grpcpp/server.h> |
||||
|
||||
namespace grpc_impl { |
||||
|
||||
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD |
||||
|
||||
/// Add a new client to a \a Server communicating over the given
|
||||
/// file descriptor.
|
||||
///
|
||||
/// \param server The server to add the client to.
|
||||
/// \param fd The file descriptor representing a socket.
|
||||
void AddInsecureChannelFromFd(grpc::Server* server, int fd); |
||||
|
||||
#endif // GPR_SUPPORT_CHANNELS_FROM_FD
|
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCPP_SERVER_POSIX_IMPL_H
|
@ -0,0 +1,48 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2017 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_SUPPORT_ERROR_DETAILS_IMPL_H |
||||
#define GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H |
||||
|
||||
#include <grpcpp/support/status.h> |
||||
|
||||
namespace google { |
||||
namespace rpc { |
||||
class Status; |
||||
} // namespace rpc
|
||||
} // namespace google
|
||||
|
||||
namespace grpc_impl { |
||||
|
||||
/// Map a \a grpc::Status to a \a google::rpc::Status.
|
||||
/// The given \a to object will be cleared.
|
||||
/// On success, returns status with OK.
|
||||
/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize.
|
||||
/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr.
|
||||
grpc::Status ExtractErrorDetails(const grpc::Status& from, |
||||
::google::rpc::Status* to); |
||||
|
||||
/// Map \a google::rpc::Status to a \a grpc::Status.
|
||||
/// Returns OK on success.
|
||||
/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr.
|
||||
grpc::Status SetErrorDetails(const ::google::rpc::Status& from, |
||||
grpc::Status* to); |
||||
|
||||
} // namespace grpc_impl
|
||||
|
||||
#endif // GRPCPP_SUPPORT_ERROR_DETAILS_IMPL_H
|
@ -0,0 +1,419 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2017 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 GRPC_CORE_LIB_GPRPP_MAP_H |
||||
#define GRPC_CORE_LIB_GPRPP_MAP_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <string.h> |
||||
#include <functional> |
||||
#include <iterator> |
||||
#include "src/core/lib/gpr/useful.h" |
||||
#include "src/core/lib/gprpp/memory.h" |
||||
#include "src/core/lib/gprpp/pair.h" |
||||
|
||||
namespace grpc_core { |
||||
struct StringLess { |
||||
bool operator()(const char* a, const char* b) const { |
||||
return strcmp(a, b) < 0; |
||||
} |
||||
bool operator()(const UniquePtr<char>& k1, const UniquePtr<char>& k2) { |
||||
return strcmp(k1.get(), k2.get()) < 0; |
||||
} |
||||
}; |
||||
|
||||
namespace testing { |
||||
class MapTest; |
||||
} |
||||
|
||||
// Alternative map implementation for grpc_core
|
||||
template <class Key, class T, class Compare = std::less<Key>> |
||||
class Map { |
||||
public: |
||||
typedef Key key_type; |
||||
typedef T mapped_type; |
||||
typedef Pair<key_type, mapped_type> value_type; |
||||
typedef Compare key_compare; |
||||
class iterator; |
||||
|
||||
~Map() { clear(); } |
||||
|
||||
T& operator[](key_type&& key); |
||||
T& operator[](const key_type& key); |
||||
iterator find(const key_type& k); |
||||
size_t erase(const key_type& key); |
||||
// Removes the current entry and points to the next one
|
||||
iterator erase(iterator iter); |
||||
|
||||
size_t size() { return size_; } |
||||
|
||||
template <class... Args> |
||||
Pair<iterator, bool> emplace(Args&&... args); |
||||
|
||||
Pair<iterator, bool> insert(value_type&& pair) { |
||||
return emplace(std::move(pair)); |
||||
} |
||||
|
||||
Pair<iterator, bool> insert(const value_type& pair) { return emplace(pair); } |
||||
|
||||
bool empty() const { return root_ == nullptr; } |
||||
|
||||
void clear() { |
||||
auto iter = begin(); |
||||
while (!empty()) { |
||||
iter = erase(iter); |
||||
} |
||||
} |
||||
|
||||
iterator begin() { |
||||
Entry* curr = GetMinEntry(root_); |
||||
return iterator(this, curr); |
||||
} |
||||
|
||||
iterator end() { return iterator(this, nullptr); } |
||||
|
||||
private: |
||||
friend class testing::MapTest; |
||||
struct Entry { |
||||
explicit Entry(value_type&& pair) : pair(std::move(pair)) {} |
||||
value_type pair; |
||||
Entry* left = nullptr; |
||||
Entry* right = nullptr; |
||||
int32_t height = 1; |
||||
}; |
||||
|
||||
static int32_t EntryHeight(const Entry* e) { |
||||
return e == nullptr ? 0 : e->height; |
||||
} |
||||
|
||||
static Entry* GetMinEntry(Entry* e); |
||||
Entry* InOrderSuccessor(const Entry* e) const; |
||||
static Entry* RotateLeft(Entry* e); |
||||
static Entry* RotateRight(Entry* e); |
||||
static Entry* RebalanceTreeAfterInsertion(Entry* root, const key_type& k); |
||||
static Entry* RebalanceTreeAfterDeletion(Entry* root); |
||||
// Returns a pair with the first value being an iterator pointing to the
|
||||
// inserted entry and the second value being the new root of the subtree
|
||||
// after a rebalance
|
||||
Pair<iterator, Entry*> InsertRecursive(Entry* root, value_type&& p); |
||||
static Entry* RemoveRecursive(Entry* root, const key_type& k); |
||||
// Return 0 if lhs = rhs
|
||||
// 1 if lhs > rhs
|
||||
// -1 if lhs < rhs
|
||||
static int CompareKeys(const Key& lhs, const Key& rhs); |
||||
|
||||
Entry* root_ = nullptr; |
||||
size_t size_ = 0; |
||||
}; |
||||
|
||||
template <class Key, class T, class Compare> |
||||
class Map<Key, T, Compare>::iterator |
||||
: public std::iterator<std::input_iterator_tag, Pair<Key, T>, int32_t, |
||||
Pair<Key, T>*, Pair<Key, T>&> { |
||||
public: |
||||
iterator(const iterator& iter) : curr_(iter.curr_), map_(iter.map_) {} |
||||
bool operator==(const iterator& rhs) const { return (curr_ == rhs.curr_); } |
||||
bool operator!=(const iterator& rhs) const { return (curr_ != rhs.curr_); } |
||||
|
||||
iterator& operator++() { |
||||
curr_ = map_->InOrderSuccessor(curr_); |
||||
return *this; |
||||
} |
||||
|
||||
iterator operator++(int) { |
||||
Entry* prev = curr_; |
||||
curr_ = map_->InOrderSuccessor(curr_); |
||||
return iterator(map_, prev); |
||||
} |
||||
|
||||
iterator& operator=(const iterator& other) { |
||||
if (this != &other) { |
||||
this->curr_ = other.curr_; |
||||
this->map_ = other.map_; |
||||
} |
||||
return *this; |
||||
} |
||||
|
||||
// operator*()
|
||||
value_type& operator*() { return curr_->pair; } |
||||
const value_type& operator*() const { return curr_->pair; } |
||||
|
||||
// operator->()
|
||||
value_type* operator->() { return &curr_->pair; } |
||||
value_type const* operator->() const { return &curr_->pair; } |
||||
|
||||
private: |
||||
friend class Map<key_type, mapped_type, key_compare>; |
||||
using GrpcMap = typename ::grpc_core::Map<Key, T, Compare>; |
||||
iterator(GrpcMap* map, Entry* curr) : curr_(curr), map_(map) {} |
||||
Entry* curr_; |
||||
GrpcMap* map_; |
||||
}; |
||||
|
||||
template <class Key, class T, class Compare> |
||||
T& Map<Key, T, Compare>::operator[](key_type&& key) { |
||||
auto iter = find(key); |
||||
if (iter == end()) { |
||||
return emplace(std::move(key), T()).first->second; |
||||
} |
||||
return iter->second; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
T& Map<Key, T, Compare>::operator[](const key_type& key) { |
||||
auto iter = find(key); |
||||
if (iter == end()) { |
||||
return emplace(key, T()).first->second; |
||||
} |
||||
return iter->second; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::iterator Map<Key, T, Compare>::find( |
||||
const key_type& k) { |
||||
Entry* iter = root_; |
||||
while (iter != nullptr) { |
||||
int comp = CompareKeys(iter->pair.first, k); |
||||
if (comp == 0) { |
||||
return iterator(this, iter); |
||||
} else if (comp < 0) { |
||||
iter = iter->right; |
||||
} else { |
||||
iter = iter->left; |
||||
} |
||||
} |
||||
return end(); |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
template <class... Args> |
||||
typename ::grpc_core::Pair<typename Map<Key, T, Compare>::iterator, bool> |
||||
Map<Key, T, Compare>::emplace(Args&&... args) { |
||||
Pair<key_type, mapped_type> pair(std::forward<Args>(args)...); |
||||
iterator ret = find(pair.first); |
||||
bool insertion = false; |
||||
if (ret == end()) { |
||||
Pair<iterator, Entry*> p = InsertRecursive(root_, std::move(pair)); |
||||
root_ = p.second; |
||||
ret = p.first; |
||||
insertion = true; |
||||
size_++; |
||||
} |
||||
return MakePair(ret, insertion); |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
size_t Map<Key, T, Compare>::erase(const key_type& key) { |
||||
iterator it = find(key); |
||||
if (it == end()) return 0; |
||||
erase(it); |
||||
return 1; |
||||
} |
||||
|
||||
// TODO(mhaidry): Modify erase to use the iterator location
|
||||
// to create an efficient erase method
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::iterator Map<Key, T, Compare>::erase( |
||||
iterator iter) { |
||||
if (iter == end()) return iter; |
||||
key_type& del_key = iter->first; |
||||
iter++; |
||||
root_ = RemoveRecursive(root_, del_key); |
||||
size_--; |
||||
return iter; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* Map<Key, T, Compare>::InOrderSuccessor( |
||||
const Entry* e) const { |
||||
if (e->right != nullptr) { |
||||
return GetMinEntry(e->right); |
||||
} |
||||
Entry* successor = nullptr; |
||||
Entry* iter = root_; |
||||
while (iter != nullptr) { |
||||
int comp = CompareKeys(iter->pair.first, e->pair.first); |
||||
if (comp > 0) { |
||||
successor = iter; |
||||
iter = iter->left; |
||||
} else if (comp < 0) { |
||||
iter = iter->right; |
||||
} else |
||||
break; |
||||
} |
||||
return successor; |
||||
} |
||||
|
||||
// Returns a pair with the first value being an iterator pointing to the
|
||||
// inserted entry and the second value being the new root of the subtree
|
||||
// after a rebalance
|
||||
template <class Key, class T, class Compare> |
||||
typename ::grpc_core::Pair<typename Map<Key, T, Compare>::iterator, |
||||
typename Map<Key, T, Compare>::Entry*> |
||||
Map<Key, T, Compare>::InsertRecursive(Entry* root, value_type&& p) { |
||||
if (root == nullptr) { |
||||
Entry* e = New<Entry>(std::move(p)); |
||||
return MakePair(iterator(this, e), e); |
||||
} |
||||
int comp = CompareKeys(root->pair.first, p.first); |
||||
if (comp > 0) { |
||||
Pair<iterator, Entry*> ret = InsertRecursive(root->left, std::move(p)); |
||||
root->left = ret.second; |
||||
ret.second = RebalanceTreeAfterInsertion(root, ret.first->first); |
||||
return ret; |
||||
} else if (comp < 0) { |
||||
Pair<iterator, Entry*> ret = InsertRecursive(root->right, std::move(p)); |
||||
root->right = ret.second; |
||||
ret.second = RebalanceTreeAfterInsertion(root, ret.first->first); |
||||
return ret; |
||||
} else { |
||||
root->pair = std::move(p); |
||||
return MakePair(iterator(this, root), root); |
||||
} |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* Map<Key, T, Compare>::GetMinEntry( |
||||
Entry* e) { |
||||
if (e != nullptr) { |
||||
while (e->left != nullptr) { |
||||
e = e->left; |
||||
} |
||||
} |
||||
return e; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* Map<Key, T, Compare>::RotateLeft( |
||||
Entry* e) { |
||||
Entry* rightChild = e->right; |
||||
Entry* rightLeftChild = rightChild->left; |
||||
rightChild->left = e; |
||||
e->right = rightLeftChild; |
||||
e->height = 1 + GPR_MAX(EntryHeight(e->left), EntryHeight(e->right)); |
||||
rightChild->height = 1 + GPR_MAX(EntryHeight(rightChild->left), |
||||
EntryHeight(rightChild->right)); |
||||
return rightChild; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* Map<Key, T, Compare>::RotateRight( |
||||
Entry* e) { |
||||
Entry* leftChild = e->left; |
||||
Entry* leftRightChild = leftChild->right; |
||||
leftChild->right = e; |
||||
e->left = leftRightChild; |
||||
e->height = 1 + GPR_MAX(EntryHeight(e->left), EntryHeight(e->right)); |
||||
leftChild->height = |
||||
1 + GPR_MAX(EntryHeight(leftChild->left), EntryHeight(leftChild->right)); |
||||
return leftChild; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* |
||||
Map<Key, T, Compare>::RebalanceTreeAfterInsertion(Entry* root, |
||||
const key_type& k) { |
||||
root->height = 1 + GPR_MAX(EntryHeight(root->left), EntryHeight(root->right)); |
||||
int32_t heightDifference = EntryHeight(root->left) - EntryHeight(root->right); |
||||
if (heightDifference > 1 && CompareKeys(root->left->pair.first, k) > 0) { |
||||
return RotateRight(root); |
||||
} |
||||
if (heightDifference < -1 && CompareKeys(root->right->pair.first, k) < 0) { |
||||
return RotateLeft(root); |
||||
} |
||||
if (heightDifference > 1 && CompareKeys(root->left->pair.first, k) < 0) { |
||||
root->left = RotateLeft(root->left); |
||||
return RotateRight(root); |
||||
} |
||||
if (heightDifference < -1 && CompareKeys(root->right->pair.first, k) > 0) { |
||||
root->right = RotateRight(root->right); |
||||
return RotateLeft(root); |
||||
} |
||||
return root; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* |
||||
Map<Key, T, Compare>::RebalanceTreeAfterDeletion(Entry* root) { |
||||
root->height = 1 + GPR_MAX(EntryHeight(root->left), EntryHeight(root->right)); |
||||
int32_t heightDifference = EntryHeight(root->left) - EntryHeight(root->right); |
||||
if (heightDifference > 1) { |
||||
int leftHeightDifference = |
||||
EntryHeight(root->left->left) - EntryHeight(root->left->right); |
||||
if (leftHeightDifference < 0) { |
||||
root->left = RotateLeft(root->left); |
||||
} |
||||
return RotateRight(root); |
||||
} |
||||
if (heightDifference < -1) { |
||||
int rightHeightDifference = |
||||
EntryHeight(root->right->left) - EntryHeight(root->right->right); |
||||
if (rightHeightDifference > 0) { |
||||
root->right = RotateRight(root->right); |
||||
} |
||||
return RotateLeft(root); |
||||
} |
||||
return root; |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
typename Map<Key, T, Compare>::Entry* Map<Key, T, Compare>::RemoveRecursive( |
||||
Entry* root, const key_type& k) { |
||||
if (root == nullptr) return root; |
||||
int comp = CompareKeys(root->pair.first, k); |
||||
if (comp > 0) { |
||||
root->left = RemoveRecursive(root->left, k); |
||||
} else if (comp < 0) { |
||||
root->right = RemoveRecursive(root->right, k); |
||||
} else { |
||||
Entry* ret; |
||||
if (root->left == nullptr) { |
||||
ret = root->right; |
||||
Delete(root); |
||||
return ret; |
||||
} else if (root->right == nullptr) { |
||||
ret = root->left; |
||||
Delete(root); |
||||
return ret; |
||||
} else { |
||||
ret = root->right; |
||||
while (ret->left != nullptr) { |
||||
ret = ret->left; |
||||
} |
||||
root->pair.swap(ret->pair); |
||||
root->right = RemoveRecursive(root->right, ret->pair.first); |
||||
} |
||||
} |
||||
return RebalanceTreeAfterDeletion(root); |
||||
} |
||||
|
||||
template <class Key, class T, class Compare> |
||||
int Map<Key, T, Compare>::CompareKeys(const key_type& lhs, |
||||
const key_type& rhs) { |
||||
key_compare compare; |
||||
bool left_comparison = compare(lhs, rhs); |
||||
bool right_comparison = compare(rhs, lhs); |
||||
// Both values are equal
|
||||
if (!left_comparison && !right_comparison) { |
||||
return 0; |
||||
} |
||||
return left_comparison ? -1 : 1; |
||||
} |
||||
} // namespace grpc_core
|
||||
#endif /* GRPC_CORE_LIB_GPRPP_MAP_H */ |
@ -0,0 +1,38 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2017 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 GRPC_CORE_LIB_GPRPP_PAIR_H |
||||
#define GRPC_CORE_LIB_GPRPP_PAIR_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <utility> |
||||
|
||||
namespace grpc_core { |
||||
template <class T1, class T2> |
||||
using Pair = std::pair<T1, T2>; |
||||
|
||||
template <class T1, class T2> |
||||
inline Pair<typename std::decay<T1>::type, typename std::decay<T2>::type> |
||||
MakePair(T1&& u, T2&& v) { |
||||
typedef typename std::decay<T1>::type V1; |
||||
typedef typename std::decay<T2>::type V2; |
||||
return Pair<V1, V2>(std::forward<T1>(u), std::forward<T2>(v)); |
||||
} |
||||
} // namespace grpc_core
|
||||
#endif /* GRPC_CORE_LIB_GPRPP_PAIR_H */ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue