diff --git a/.gitmodules b/.gitmodules index ce647f3c455..d41b8d5213f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "third_party/protobuf"] path = third_party/protobuf url = https://github.com/google/protobuf.git - branch = 3.0.0-beta-3 + branch = 3.0.0-GA [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/gflags/gflags.git diff --git a/BUILD b/BUILD index 8f1ddb4bf94..006d92c909f 100644 --- a/BUILD +++ b/BUILD @@ -1259,6 +1259,7 @@ cc_library( "src/cpp/common/secure_auth_context.h", "src/cpp/server/secure_server_credentials.h", "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/client/secure_credentials.cc", @@ -1276,6 +1277,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", @@ -1490,6 +1492,7 @@ cc_library( name = "grpc++_unsecure", srcs = [ "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/common/insecure_create_auth_context.cc", @@ -1502,6 +1505,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index dd6a8d93cb7..8eb408a7209 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1004,6 +1004,7 @@ add_library(grpc++ src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc @@ -1259,6 +1260,7 @@ add_library(grpc++_unsecure src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc diff --git a/Makefile b/Makefile index f9afbd37852..b2beb992a17 100644 --- a/Makefile +++ b/Makefile @@ -1041,6 +1041,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test +filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli @@ -1406,6 +1407,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -1491,6 +1493,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -1783,6 +1786,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 ) $(E) "[RUN] Testing end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing filter_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" @@ -3594,6 +3599,7 @@ LIBGRPC++_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -4130,6 +4136,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -11245,6 +11252,49 @@ endif endif +FILTER_END2END_TEST_SRC = \ + test/cpp/end2end/filter_end2end_test.cc \ + +FILTER_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FILTER_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/filter_end2end_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/filter_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(FILTER_END2END_TEST_OBJS:.o=.dep) +endif +endif + + GENERIC_END2END_TEST_SRC = \ test/cpp/end2end/generic_end2end_test.cc \ diff --git a/build.yaml b/build.yaml index 8499a0a4bb4..0ed10a483a9 100644 --- a/build.yaml +++ b/build.yaml @@ -696,6 +696,7 @@ filegroups: - include/grpc++/support/time.h headers: - src/cpp/client/create_channel_internal.h + - src/cpp/common/channel_filter.h - src/cpp/server/dynamic_thread_pool.h - src/cpp/server/thread_pool_interface.h src: @@ -708,6 +709,7 @@ filegroups: - src/cpp/client/generic_stub.cc - src/cpp/client/insecure_credentials.cc - src/cpp/common/channel_arguments.cc + - src/cpp/common/channel_filter.cc - src/cpp/common/completion_queue.cc - src/cpp/common/core_codegen.cc - src/cpp/common/rpc_method.cc @@ -827,7 +829,6 @@ libs: - grpc_lb_policy_grpclb - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - - grpc_lb_policy_grpclb - grpc_resolver_dns_native - grpc_resolver_sockaddr - grpc_load_reporting @@ -926,7 +927,6 @@ libs: - grpc_lb_policy_grpclb - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - - grpc_lb_policy_grpclb - census generate_plugin_registry: true secure: false @@ -2690,6 +2690,19 @@ targets: - grpc - gpr_test_util - gpr +- name: filter_end2end_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/filter_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: generic_end2end_test gtest: true build: test diff --git a/doc/health-checking.md b/doc/health-checking.md index 92512e942bd..7be8107b60f 100644 --- a/doc/health-checking.md +++ b/doc/health-checking.md @@ -58,7 +58,7 @@ a response must be sent back with an `OK` status and the status field should be set to `SERVING` or `NOT_SERVING` accordingly. If the service name is not registered, the server returns a `NOT_FOUND` GRPC status. -The server should use an empty string as the key for server’s +The server should use an empty string as the key for server's overall health status, so that a client not interested in a specific service can query the server's status with an empty request. The server can just do exact matching of the service name without support of any kind of wildcard matching. diff --git a/examples/cpp/README.md b/examples/cpp/README.md index 3fa7ad4c784..783935cd53d 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -2,26 +2,14 @@ ## Installation -To install gRPC on your system, follow the instructions to build from source [here](../../INSTALL.md). This also installs the protocol buffer compiler `protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. +To install gRPC on your system, follow the instructions to build from source +[here](../../INSTALL.md). This also installs the protocol buffer compiler +`protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](../protos/helloworld.proto) example used in [Getting started](..). - -The example code for this and our other examples lives in the `examples` -directory. Clone this repository to your local machine by running the -following command: - - -```sh -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Change your current directory to examples/cpp/helloworld - -```sh -$ cd examples/cpp/helloworld/ -``` +Here's how to build and run the C++ implementation of the [Hello +World](../protos/helloworld.proto) example used in [Getting started](..). ### Client and server implementations @@ -31,18 +19,25 @@ The server implementation is at [greeter_server.cc](helloworld/greeter_server.cc ### Try it! Build client and server: + ```sh $ make ``` + Run the server, which will listen on port 50051: + ```sh $ ./greeter_server ``` + Run the client (in a different terminal): + ```sh $ ./greeter_client ``` -If things go smoothly, you will see the "Greeter received: Hello world" in the client side output. + +If things go smoothly, you will see the "Greeter received: Hello world" in the +client side output. ## Tutorial diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index 80fef07192e..de7e4b26365 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -1,58 +1,77 @@ #gRPC Basics: C++ -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: +This tutorial provides a basic C++ programmer's introduction to working with +gRPC. By walking through this example you'll learn how to: -- Define a service in a .proto file. +- Define a service in a `.proto` file. - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](..) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. +It assumes that you are familiar with +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol +buffers language, which is currently in alpha release: you can find out more in +the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the +new version in the protocol buffers Github repository. ## Why use gRPC? -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. +Our example is a simple route mapping application that lets clients get +information about features on their route, create a summary of their route, and +exchange route information such as traffic updates with the server and other +clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. +With gRPC we can define our service once in a `.proto` file and implement clients +and servers in any of gRPC's supported languages, which in turn can be run in +environments ranging from servers inside Google to your own tablet - all the +complexity of communication between different languages and environments is +handled for you by gRPC. We also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface +updating. ## Example code and setup -The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command: -```shell -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Then change your current directory to `examples/cpp/route_guide`: -```shell -$ cd examples/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [gRPC in 3 minutes](README.md). - +The example code for our tutorial is in [examples/cpp/route_guide](route_guide). +You also should have the relevant tools installed to generate the server and +client interface code - if you don't already, follow the setup instructions in +[INSTALL.md](../../INSTALL.md). ## Defining the service -Our first step (as you'll know from [Getting started](..) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](../protos/route_guide.proto). +Our first step is to define the gRPC *service* and the method *request* and +*response* types using +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete `.proto` file in +[`examples/protos/route_guide.proto`](../protos/route_guide.proto). -To define a service, you specify a named `service` in your .proto file: +To define a service, you specify a named `service` in your `.proto` file: -``` +```protobuf service RouteGuide { ... } ``` -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: +Then you define `rpc` methods inside your service definition, specifying their +request and response types. gRPC lets you define four kinds of service method, +all of which are used in the `RouteGuide` service: -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` +- A *simple RPC* where the client sends a request to the server using the stub + and waits for a response to come back, just like a normal function call. + +```protobuf // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` +- A *server-side streaming RPC* where the client sends a request to the server + and gets a stream to read a sequence of messages back. The client reads from + the returned stream until there are no more messages. As you can see in our + example, you specify a server-side streaming method by placing the `stream` + keyword before the *response* type. + +```protobuf // Obtains the Features available within the given Rectangle. Results are // streamed rather than returned at once (e.g. in a response message with a // repeated field), as the rectangle may cover a large area and contain a @@ -60,22 +79,38 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` +- A *client-side streaming RPC* where the client writes a sequence of messages + and sends them to the server, again using a provided stream. Once the client + has finished writing the messages, it waits for the server to read them all + and return its response. You specify a client-side streaming method by placing + the `stream` keyword before the *request* type. + +```protobuf // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` +- A *bidirectional streaming RPC* where both sides send a sequence of messages + using a read-write stream. The two streams operate independently, so clients + and servers can read and write in whatever order they like: for example, the + server could wait to receive all the client messages before writing its + responses, or it could alternately read a message then write a message, or + some other combination of reads and writes. The order of messages in each + stream is preserved. You specify this type of method by placing the `stream` + keyword before both the request and the response. + +```protobuf // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` +Our `.proto` file also contains protocol buffer message type definitions for all +the request and response types used in our service methods - for example, here's +the `Point` message type: + +```protobuf // Points are represented as latitude-longitude pairs in the E7 representation // (degrees multiplied by 10**7 and rounded to the nearest integer). // Latitudes should be in the range +/- 90 degrees and longitude should be in @@ -86,12 +121,16 @@ message Point { } ``` - ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. +Next we need to generate the gRPC client and server interfaces from our `.proto` +service definition. We do this using the protocol buffer compiler `protoc` with +a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL.md) first): +For simplicity, we've provided a [makefile](route_guide/Makefile) that runs +`protoc` for you with the appropriate plugin, input, and output (if you want to +run this yourself, make sure you've installed protoc and followed the gRPC code +[installation instructions](../../INSTALL.md) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -107,39 +146,58 @@ $ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto Running this command generates the following files in your current directory: - `route_guide.pb.h`, the header which declares your generated message classes - `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes +- `route_guide.grpc.pb.h`, the header which declares your generated service + classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service + classes These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- All the protocol buffer code to populate, serialize, and retrieve our request + and response message types - A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + - a remote interface type (or *stub*) for clients to call with the methods + defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods + defined in the `RouteGuide` service. ## Creating the server -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). +First let's look at how we create a `RouteGuide` server. If you're only +interested in creating gRPC clients, you can skip this section and go straight +to [Creating the client](#client) (though you might find it interesting +anyway!). There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. +- Implementing the service interface generated from our service definition: + doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the + service responses. -You can find our example `RouteGuide` server in [route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in +[route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's +take a closer look at how it works. ### Implementing RouteGuide -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: +As you can see, our server has a `RouteGuideImpl` class that implements the +generated `RouteGuide::Service` interface: ```cpp class RouteGuideImpl final : public RouteGuide::Service { ... } ``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. +In this case we're implementing the *synchronous* version of `RouteGuide`, which +provides our default gRPC server behaviour. It's also possible to implement an +asynchronous interface, `RouteGuide::AsyncService`, which allows you to further +customize your server's threading behaviour, though we won't look at this in +this tutorial. -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. +`RouteGuideImpl` implements all our service methods. Let's look at the simplest +type first, `GetFeature`, which just gets a `Point` from the client and returns +the corresponding feature information from its database in a `Feature`. ```cpp Status GetFeature(ServerContext* context, const Point* point, @@ -150,34 +208,52 @@ In this case we're implementing the *synchronous* version of `RouteGuide`, which } ``` -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. +The method is passed a context object for the RPC, the client's `Point` protocol +buffer request, and a `Feature` protocol buffer to fill in with the response +information. In the method we populate the `Feature` with the appropriate +information, and then `return` with an `OK` status to tell gRPC that we've +finished dealing with the RPC and that the `Feature` can be returned to the +client. -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. +Now let's look at something a bit more complicated - a streaming RPC. +`ListFeatures` is a server-side streaming RPC, so we need to send back multiple +`Feature`s to our client. ```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } +Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); } - return Status::OK; } + return Status::OK; +} ``` -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. +As you can see, instead of getting simple request and response objects in our +method parameters, this time we get a request object (the `Rectangle` in which +our client wants to find `Feature`s) and a special `ServerWriter` object. In the +method, we populate as many `Feature` objects as we need to return, writing them +to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, +we `return Status::OK` to tell gRPC that we've finished writing responses. -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. +If you look at the client-side streaming method `RecordRoute` you'll see it's +quite similar, except this time we get a `ServerReader` instead of a request +object and a single response. We use the `ServerReader`s `Read()` method to +repeatedly read in our client's requests to a request object (in this case a +`Point`) until there are no more messages: the server needs to check the return +value of `Read()` after each call. If `true`, the stream is still good and it +can continue reading; if `false` the message stream has ended. ```cpp while (stream->Read(&point)) { @@ -205,11 +281,18 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat()`. } ``` -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +This time we get a `ServerReaderWriter` that can be used to read *and* write +messages. The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ### Starting the server -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: +Once we've implemented all our methods, we also need to start up a gRPC server +so that clients can actually use our service. The following snippet shows how we +do this for our `RouteGuide` service: ```cpp void RunServer(const std::string& db_path) { @@ -227,44 +310,55 @@ void RunServer(const std::string& db_path) { As you can see, we build and start our server using a `ServerBuilder`. To do this, we: 1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. +1. Create an instance of the factory `ServerBuilder` class. +1. Specify the address and port we want to use to listen for client requests + using the builder's `AddListeningPort()` method. +1. Register our service implementation with the builder. +1. Call `BuildAndStart()` on the builder to create and start an RPC server for + our service. +1. Call `Wait()` on the server to do a blocking wait until process is killed or + `Shutdown()` is called. ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` +service. You can see our complete example client code in +[route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). ### Creating a stub To call service methods, we first need to create a *stub*. -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL: +First we need to create a gRPC *channel* for our stub, specifying the server +address and port we want to connect to without SSL: ```cpp grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); ``` -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. +Now we can use the channel to create our stub using the `NewStub` method +provided in the `RouteGuide` class we generated from our `.proto`. ```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } +public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } ``` ### Calling service methods -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +Now let's look at how we call our service methods. Note that in this tutorial +we're calling the *blocking/synchronous* versions of each method: this means +that the RPC call waits for the server to respond, and will either return a +response or raise an exception. #### Simple RPC -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a +local method. ```cpp Point point; @@ -281,33 +375,53 @@ Calling the simple RPC `GetFeature` is nearly as straightforward as calling a lo } ``` -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. +As you can see, we create and populate a request protocol buffer object (in our +case `Point`), and create a response protocol buffer object for the server to +fill in. We also create a `ClientContext` object for our call - you can +optionally set RPC configuration values on this object, such as deadlines, +though for now we'll use the default settings. Note that you cannot reuse this +object between calls. Finally, we call the method on the stub, passing it the +context, request, and response. If the method returns `OK`, then we can read the +response information from the server from our response object. ```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; +std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; ``` #### Streaming RPCs -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: +Now let's look at our streaming methods. If you've already read [Creating the +server](#server) some of this may look very familiar - streaming RPCs are +implemented in a similar way on both sides. Here's where we call the server-side +streaming method `ListFeatures`, which returns a stream of geographical +`Feature`s: ```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); +std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); +while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; +} +Status status = reader->Finish(); ``` -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. +Instead of passing the method a context, request, and response, we pass it a +context and request and get a `ClientReader` object back. The client can use the +`ClientReader` to read the server's responses. We use the `ClientReader`s +`Read()` method to repeatedly read in the server's responses to a response +protocol buffer object (in this case a `Feature`) until there are no more +messages: the client needs to check the return value of `Read()` after each +call. If `true`, the stream is still good and it can continue reading; if +`false` the message stream has ended. Finally, we call `Finish()` on the stream +to complete the call and get our RPC status. -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. +The client-side streaming method `RecordRoute` is similar, except there we pass +the method a context and response object and get back a `ClientWriter`. ```cpp std::unique_ptr > writer( @@ -337,16 +451,26 @@ The client-side streaming method `RecordRoute` is similar, except there we pass } ``` -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. +Once we've finished writing our client's requests to the stream using `Write()`, +we need to call `WritesDone()` on the stream to let gRPC know that we've +finished writing, then `Finish()` to complete the call and get our RPC status. +If the status is `OK`, our response object that we initially passed to +`RecordRoute()` will be populated with the server's response. -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this +case, we just pass a context to the method and get back a `ClientReaderWriter`, +which we can use to both write and read messages. ```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); +std::shared_ptr > stream( + stub_->RouteChat(&context)); ``` -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ## Try it out! @@ -362,4 +486,3 @@ Run the client (in a different terminal): ```shell $ ./route_guide_client ``` - diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index df82f4688fc..2c50b8208b1 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -107,7 +107,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-3.3" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index ba5e45c05c2..00cf9ad4e62 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -96,7 +96,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @echo "Please install Google protocol buffers 3.0.0 and its compiler." @echo "You can find it here:" @echo - @echo " https://github.com/google/protobuf/releases/tag/v3.0.0-beta-3.3" + @echo " https://github.com/google/protobuf/releases/tag/v3.0.0" @echo @echo "Here is what I get when trying to evaluate your version of protoc:" @echo diff --git a/examples/csharp/helloworld/.nuget/packages.config b/examples/csharp/helloworld/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/helloworld/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/helloworld/Greeter.sln b/examples/csharp/helloworld/Greeter.sln index 9430e94de99..49e364d91c0 100644 --- a/examples/csharp/helloworld/Greeter.sln +++ b/examples/csharp/helloworld/Greeter.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterSer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config index ff9d6bbf73f..c94bb873073 100644 --- a/examples/csharp/helloworld/Greeter/packages.config +++ b/examples/csharp/helloworld/Greeter/packages.config @@ -4,4 +4,5 @@ + \ No newline at end of file diff --git a/examples/csharp/route_guide/.nuget/packages.config b/examples/csharp/route_guide/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/route_guide/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuide.sln b/examples/csharp/route_guide/RouteGuide.sln index 0b79fdc5ca7..00065b0ba9d 100644 --- a/examples/csharp/route_guide/RouteGuide.sln +++ b/examples/csharp/route_guide/RouteGuide.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj index 601d16ba24d..942d94f66c7 100644 --- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -45,15 +45,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj index 5bf46b05b89..4ffc5ccca98 100644 --- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj @@ -47,15 +47,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config index b962a7232a9..916fe4c01db 100644 --- a/examples/csharp/route_guide/RouteGuideServer/packages.config +++ b/examples/csharp/route_guide/RouteGuideServer/packages.config @@ -5,4 +5,5 @@ + \ No newline at end of file diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index d709c7e636f..afccf08bbf1 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index 48364fc0af1..9f07bd6b305 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index 04bc10bc0b5..7e7e01d8781 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md index 4e74a79f136..26f1704f122 100644 --- a/examples/php/route_guide/README.md +++ b/examples/php/route_guide/README.md @@ -1,6 +1,6 @@ #gRPC Basics: PHP sample code The files in this folder are the samples used in [gRPC Basics: PHP][], -a detailed tutorial for using gRPC in Ruby. +a detailed tutorial for using gRPC in PHP. [gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 4e780a70a19..3ffe6784768 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -68,7 +68,7 @@ def get_distance(start, end): R = 6371000; # metres return R * c; -class RouteGuideServicer(route_guide_pb2.BetaRouteGuideServicer): +class RouteGuideServicer(route_guide_pb2.RouteGuideServicer): """Provides methods that implement functionality of route guide server.""" def __init__(self): diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 741067b23f4..f3a83430419 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # @@ -61,7 +55,7 @@ Pod::Spec.new do |s| s.dependency 'gRPC', version s.dependency 'gRPC-RxLibrary', version - s.dependency 'Protobuf', '~> 3.0.0-beta-3.1' + s.dependency 'Protobuf', '~> 3.0' # This is needed by all pods that depend on Protobuf: s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 862ed8974ba..9936d52df55 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # diff --git a/gRPC.podspec b/gRPC.podspec index eda965a3280..3f6da3b141d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # diff --git a/include/grpc++/ext/reflection.pb.h b/include/grpc++/ext/reflection.pb.h index 00d07735ee8..bdb86197d03 100644 --- a/include/grpc++/ext/reflection.pb.h +++ b/include/grpc++/ext/reflection.pb.h @@ -83,7 +83,7 @@ class ServiceResponse; // =================================================================== -class ServerReflectionRequest : public ::google::protobuf::Message { +class ServerReflectionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionRequest) */ { public: ServerReflectionRequest(); virtual ~ServerReflectionRequest(); @@ -126,7 +126,11 @@ class ServerReflectionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -260,7 +264,7 @@ class ServerReflectionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionRequest : public ::google::protobuf::Message { +class ExtensionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionRequest) */ { public: ExtensionRequest(); virtual ~ExtensionRequest(); @@ -294,7 +298,11 @@ class ExtensionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -350,7 +358,7 @@ class ExtensionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServerReflectionResponse : public ::google::protobuf::Message { +class ServerReflectionResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionResponse) */ { public: ServerReflectionResponse(); virtual ~ServerReflectionResponse(); @@ -392,7 +400,11 @@ class ServerReflectionResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -505,7 +517,7 @@ class ServerReflectionResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class FileDescriptorResponse : public ::google::protobuf::Message { +class FileDescriptorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.FileDescriptorResponse) */ { public: FileDescriptorResponse(); virtual ~FileDescriptorResponse(); @@ -539,7 +551,11 @@ class FileDescriptorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -593,7 +609,7 @@ class FileDescriptorResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionNumberResponse : public ::google::protobuf::Message { +class ExtensionNumberResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionNumberResponse) */ { public: ExtensionNumberResponse(); virtual ~ExtensionNumberResponse(); @@ -627,7 +643,11 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -690,7 +710,7 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ListServiceResponse : public ::google::protobuf::Message { +class ListServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ListServiceResponse) */ { public: ListServiceResponse(); virtual ~ListServiceResponse(); @@ -724,7 +744,11 @@ class ListServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -774,7 +798,7 @@ class ListServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServiceResponse : public ::google::protobuf::Message { +class ServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServiceResponse) */ { public: ServiceResponse(); virtual ~ServiceResponse(); @@ -808,7 +832,11 @@ class ServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -857,7 +885,7 @@ class ServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ErrorResponse : public ::google::protobuf::Message { +class ErrorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ErrorResponse) */ { public: ErrorResponse(); virtual ~ErrorResponse(); @@ -891,7 +919,11 @@ class ErrorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 6f7a67b715e..4ca018edb39 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -170,8 +170,9 @@ GRPCAPI void grpc_channel_watch_connectivity_state( completions are sent to 'completion_queue'. 'method' and 'host' need only live through the invocation of this function. If parent_call is non-NULL, it must be a server-side call. It will be used - to propagate properties from the server call to this new client call. - */ + to propagate properties from the server call to this new client call, + depending on the value of \a propagation_mask (see propagation_bits.h for + possible values). */ GRPCAPI grpc_call *grpc_channel_create_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, @@ -187,7 +188,8 @@ GRPCAPI void *grpc_channel_register_call(grpc_channel *channel, const char *method, const char *host, void *reserved); -/** Create a call given a handle returned from grpc_channel_register_call */ +/** Create a call given a handle returned from grpc_channel_register_call. + \sa grpc_channel_create_call. */ GRPCAPI grpc_call *grpc_channel_create_registered_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, void *registered_call_handle, diff --git a/requirements.txt b/requirements.txt index 0ec0e75b762..bf87de07f89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ coverage>=4.0 cython>=0.23 enum34>=1.0.4 futures>=2.2.0 -protobuf>=3.0.0a3 +protobuf>=3.0.0 six>=1.10 -wheel>=0.29 \ No newline at end of file +wheel>=0.29 diff --git a/setup.py b/setup.py index cad300c144a..fb9537fccdc 100644 --- a/setup.py +++ b/setup.py @@ -200,7 +200,7 @@ INSTALL_REQUIRES = ( 'futures>=2.2.0', # TODO(atash): eventually split the grpcio package into a metapackage # depending on protobuf and the runtime component (independent of protobuf) - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', ) SETUP_REQUIRES = INSTALL_REQUIRES + ( diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc index c3852020a3a..d7af125c3ae 100644 --- a/src/compiler/node_generator.cc +++ b/src/compiler/node_generator.cc @@ -114,8 +114,8 @@ map GetAllMessages( const MethodDescriptor *method = service->method(method_num); const Descriptor *input_type = method->input_type(); const Descriptor *output_type = method->output_type(); - message_types[input_type->name()] = input_type; - message_types[output_type->name()] = output_type; + message_types[input_type->full_name()] = input_type; + message_types[output_type->full_name()] = output_type; } } return message_types; @@ -127,7 +127,7 @@ grpc::string MessageIdentifierName(const grpc::string &name) { grpc::string NodeObjectPath(const Descriptor *descriptor) { grpc::string module_alias = ModuleAlias(descriptor->file()->name()); - grpc::string name = descriptor->name(); + grpc::string name = descriptor->full_name(); grpc_generator::StripPrefix(&name, descriptor->file()->package() + "."); return module_alias + "." + name; } @@ -135,8 +135,9 @@ grpc::string NodeObjectPath(const Descriptor *descriptor) { // Prints out the message serializer and deserializer functions void PrintMessageTransformer(const Descriptor *descriptor, Printer *out) { map template_vars; - template_vars["identifier_name"] = MessageIdentifierName(descriptor->name()); - template_vars["name"] = descriptor->name(); + grpc::string full_name = descriptor->full_name(); + template_vars["identifier_name"] = MessageIdentifierName(full_name); + template_vars["name"] = full_name; template_vars["node_name"] = NodeObjectPath(descriptor); // Print the serializer out->Print(template_vars, "function serialize_$identifier_name$(arg) {\n"); @@ -169,9 +170,9 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) { vars["service_name"] = method->service()->full_name(); vars["name"] = method->name(); vars["input_type"] = NodeObjectPath(input_type); - vars["input_type_id"] = MessageIdentifierName(input_type->name()); + vars["input_type_id"] = MessageIdentifierName(input_type->full_name()); vars["output_type"] = NodeObjectPath(output_type); - vars["output_type_id"] = MessageIdentifierName(output_type->name()); + vars["output_type_id"] = MessageIdentifierName(output_type->full_name()); vars["client_stream"] = method->client_streaming() ? "true" : "false"; vars["server_stream"] = method->server_streaming() ? "true" : "false"; out->Print("{\n"); diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index dec25efe616..af913d8a9df 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -767,6 +767,9 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) { lb_client->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(3, GPR_TIMESPAN)); + /* Note the following LB call progresses every time there's activity in \a + * glb_policy->base.interested_parties, which is comprised of the polling + * entities passed to glb_pick(). */ lb_client->lb_call = grpc_channel_create_pollset_set_call( glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, glb_policy->base.interested_parties, "/BalanceLoad", diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index c5e8f2f6d11..16946de853d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -802,6 +802,8 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } } +/* error may be GRPC_ERROR_NONE if there is no error allocated yet. + In that case, use "reason" as the text for a new error. */ static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, grpc_error *error) { grpc_chttp2_stream_global *stream_global; diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index ee687014569..6b73cce380f 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -51,6 +51,10 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_channel_element grpc_channel_element; typedef struct grpc_call_element grpc_call_element; @@ -291,4 +295,8 @@ extern int grpc_trace_channel; #define GRPC_CALL_LOG_OP(sev, elem, op) \ if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index 0e6bfd9aa69..4a00f7bfdbd 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -39,6 +39,10 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#ifdef __cplusplus +extern "C" { +#endif + /// grpc_channel_stack_builder offers a programmatic interface to selected /// and order channel filters typedef struct grpc_channel_stack_builder grpc_channel_stack_builder; @@ -158,4 +162,8 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); extern int grpc_trace_channel_stack_builder; +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index c50e84279d4..071c5f695c5 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -34,10 +34,19 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H #define GRPC_CORE_LIB_CHANNEL_CONTEXT_H -/* Call object context pointers */ +/// Call object context pointers. + +/// Call context is represented as an array of \a grpc_call_context_elements. +/// This enum represents the indexes into the array, where each index +/// contains a different type of value. typedef enum { + /// Value is either a \a grpc_client_security_context or a + /// \a grpc_server_security_context. GRPC_CONTEXT_SECURITY = 0, + + /// Value is a \a census_context. GRPC_CONTEXT_TRACING, + GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index 38ebd2dbcb0..ea8d2411547 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -90,10 +90,12 @@ struct grpc_tcp_listener { grpc_closure read_closure; grpc_closure destroyed_closure; struct grpc_tcp_listener *next; - /* When we add a listener, more than one can be created, mainly because of - IPv6. A sibling will still be in the normal list, but will be flagged - as such. Any action, such as ref or unref, will affect all of the - siblings in the list. */ + /* sibling is a linked list of all listeners for a given port. add_port and + clone_port place all new listeners in the same sibling list. A member of + the 'sibling' list is also a member of the 'next' list. The head of each + sibling list has is_sibling==0, and subsequent members of sibling lists + have is_sibling==1. is_sibling allows separate sibling lists to be + identified while iterating through 'next'. */ struct grpc_tcp_listener *sibling; int is_sibling; }; @@ -306,7 +308,7 @@ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr, GPR_ASSERT(fd >= 0); - if (so_reuseport) { + if (so_reuseport && !grpc_is_unix_socket(addr)) { err = grpc_set_socket_reuse_port(fd, 1); if (err != GRPC_ERROR_NONE) goto error; } @@ -480,6 +482,9 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd, return err; } +/* Insert count new listeners after listener. Every new listener will have the + same listen address as listener (SO_REUSEPORT must be enabled). Every new + listener is a sibling of listener. */ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { grpc_tcp_listener *sp = NULL; char *addr_str; @@ -506,6 +511,11 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp = gpr_malloc(sizeof(grpc_tcp_listener)); sp->next = listener->next; listener->next = sp; + /* sp (the new listener) is a sibling of 'listener' (the original + listener). */ + sp->is_sibling = 1; + sp->sibling = listener->sibling; + listener->sibling = sp; sp->server = listener->server; sp->fd = fd; sp->emfd = grpc_fd_create(fd, name); @@ -514,8 +524,6 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp->port = port; sp->port_index = listener->port_index; sp->fd_index = listener->fd_index + count - i; - sp->is_sibling = 1; - sp->sibling = listener->is_sibling ? listener->sibling : listener; GPR_ASSERT(sp->emfd); while (listener->server->tail->next != NULL) { listener->server->tail = listener->server->tail->next; @@ -685,7 +693,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, s->pollset_count = pollset_count; sp = s->head; while (sp != NULL) { - if (s->so_reuseport && pollset_count > 1) { + if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr.sockaddr) && + pollset_count > 1) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "clone_port", clone_port(sp, (unsigned)(pollset_count - 1)))); for (i = 0; i < pollset_count; i++) { diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index ef0c06b1fb6..4e7666dfe31 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -37,6 +37,10 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" +#ifdef __cplusplus +extern "C" { +#endif + /* --- grpc_auth_context --- High level authentication context object. Can optionally be chained. */ @@ -111,4 +115,8 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H */ diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 7eff7b88836..4c629743462 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -42,6 +42,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, grpc_channel_stack_type channel_stack_type, grpc_transport *optional_transport); +/** Create a call given a grpc_channel, in order to call \a method. + Progress is tied to activity on \a pollset_set. The returned call object is + meant to be used with \a grpc_call_start_batch_and_execute, which relies on + callbacks to signal completions. \a method and \a host need + only live through the invocation of this function. If \a parent_call is + non-NULL, it must be a server-side call. It will be used to propagate + properties from the server call to this new client call, depending on the + value of \a propagation_mask (see propagation_bits.h for possible values) */ grpc_call *grpc_channel_create_pollset_set_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_pollset_set *pollset_set, const char *method, const char *host, diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 3a18a61ddb8..b53f2aefb92 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -40,6 +40,10 @@ #define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000 +#ifdef __cplusplus +extern "C" { +#endif + /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. /// It also provides a universal entry path to run those mutators to build @@ -84,4 +88,8 @@ bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, grpc_channel_stack_type type); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */ diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 11795cf0c36..0827a1e1819 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -290,7 +290,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, channel_broadcaster *cb, - int send_goaway, + bool send_goaway, grpc_error *force_disconnect) { size_t i; @@ -1255,7 +1255,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server, l->destroy(&exec_ctx, server, l->arg, &l->destroy_done); } - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0); + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, true /* send_goaway */, + GRPC_ERROR_NONE); done: grpc_exec_ctx_finish(&exec_ctx); @@ -1271,7 +1272,7 @@ void grpc_server_cancel_all_calls(grpc_server *server) { channel_broadcaster_init(server, &broadcaster); gpr_mu_unlock(&server->mu_global); - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */, GRPC_ERROR_CREATE("Cancelling all calls")); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 95519a9eaf7..e64dce62837 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -59,13 +59,9 @@ struct grpc_byte_stream { * on_complete will not be called), 0 if the bytes will be available * asynchronously. * - * on entry, *remaining can be set as a hint as to the maximum number + * max_size_hint can be set as a hint as to the maximum number * of bytes that would be acceptable to read. * - * fills *buffer, *length, *remaining with the bytes, length of bytes - * and length of data remaining to be read before either returning 1 - * or calling on_complete. - * * once a slice is returned into *slice, it is owned by the caller. */ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 6d82f4d6819..2b0921c8d74 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -37,6 +37,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* This file provides a mechanism for tracking metadata through the grpc stack. It's not intended for consumption outside of the library. @@ -164,4 +168,8 @@ void grpc_mdctx_global_shutdown(void); extern gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)( gpr_slice input); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c index e4398abeb78..84b5a74d513 100644 --- a/src/core/lib/transport/metadata_batch.c +++ b/src/core/lib/transport/metadata_batch.c @@ -33,6 +33,7 @@ #include "src/core/lib/transport/metadata_batch.h" +#include #include #include @@ -187,7 +188,7 @@ void grpc_metadata_batch_clear(grpc_metadata_batch *batch) { grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL); } -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { return batch->list.head == NULL && gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type), batch->deadline) == 0; diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 7af823f7ca4..0424b4db986 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -34,12 +34,18 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H #define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H +#include + #include #include #include #include #include "src/core/lib/transport/metadata.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_linked_mdelem { grpc_mdelem *md; struct grpc_linked_mdelem *next; @@ -64,7 +70,7 @@ typedef struct grpc_metadata_batch { void grpc_metadata_batch_init(grpc_metadata_batch *batch); void grpc_metadata_batch_destroy(grpc_metadata_batch *batch); void grpc_metadata_batch_clear(grpc_metadata_batch *batch); -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); /* Returns the transport size of the batch. */ size_t grpc_metadata_batch_size(grpc_metadata_batch *batch); @@ -125,4 +131,8 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); } while (0) #endif +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 4f827942350..d0d0c2a461d 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -43,6 +43,10 @@ #include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/metadata_batch.h" +#ifdef __cplusplus +extern "C" { +#endif + /* forward declarations */ typedef struct grpc_transport grpc_transport; @@ -169,7 +173,7 @@ typedef struct grpc_transport_op { /** should we send a goaway? after a goaway is sent, once there are no more active calls on the transport, the transport should disconnect */ - int send_goaway; + bool send_goaway; /** what should the goaway contain? */ grpc_status_code goaway_status; gpr_slice *goaway_message; @@ -289,4 +293,8 @@ char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, \a on_consumed and then delete the returned transport op */ grpc_transport_op *grpc_make_transport_op(grpc_closure *on_consumed); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H */ diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc new file mode 100644 index 00000000000..25cd49cb7c9 --- /dev/null +++ b/src/cpp/common/channel_filter.cc @@ -0,0 +1,112 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/cpp/common/channel_filter.h" + +namespace grpc { + +// MetadataBatch + +grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, + const string &value) { + grpc_linked_mdelem *storage = new grpc_linked_mdelem; + memset(storage, 0, sizeof(grpc_linked_mdelem)); + storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str()); + grpc_metadata_batch_link_head(batch_, storage); + return storage; +} + +// ChannelData + +void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + TransportOp *op) { + grpc_channel_next_op(exec_ctx, elem, op->op()); +} + +// CallData + +void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + TransportStreamOp *op) { + grpc_call_next_op(exec_ctx, elem, op->op()); +} + +void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { + grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent); +} + +char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + return grpc_call_next_get_peer(exec_ctx, elem); +} + +// internal code used by RegisterChannelFilter() + +namespace internal { + +// Note: Implicitly initialized to nullptr due to static lifetime. +std::vector *channel_filters; + +namespace { + +bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) { + const FilterRecord &filter = *(FilterRecord *)arg; + if (filter.include_filter) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (!filter.include_filter(*args)) return true; + } + return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, + nullptr, nullptr); +} + +} // namespace + +void ChannelFilterPluginInit() { + for (size_t i = 0; i < channel_filters->size(); ++i) { + FilterRecord &filter = (*channel_filters)[i]; + grpc_channel_init_register_stage(filter.stack_type, filter.priority, + MaybeAddFilter, (void *)&filter); + } +} + +void ChannelFilterPluginShutdown() {} + +} // namespace internal + +} // namespace grpc diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h new file mode 100644 index 00000000000..3fbacd824c9 --- /dev/null +++ b/src/cpp/common/channel_filter.h @@ -0,0 +1,386 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_CHANNEL_FILTER_H +#define GRPCXX_CHANNEL_FILTER_H + +#include +#include +#include +#include + +#include +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/metadata_batch.h" + +/// An interface to define filters. +/// +/// To define a filter, implement a subclass of each of \c CallData and +/// \c ChannelData. Then register the filter using something like this: +/// \code{.cpp} +/// RegisterChannelFilter( +/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +/// \endcode + +namespace grpc { + +/// A C++ wrapper for the \c grpc_metadata_batch struct. +class MetadataBatch { + public: + /// Borrows a pointer to \a batch, but does NOT take ownership. + /// The caller must ensure that \a batch continues to exist for as + /// long as the MetadataBatch object does. + explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} + + grpc_metadata_batch *batch() const { return batch_; } + + /// Adds metadata and returns the newly allocated storage. + /// The caller takes ownership of the result, which must exist for the + /// lifetime of the gRPC call. + grpc_linked_mdelem *AddMetadata(const string &key, const string &value); + + class const_iterator : public std::iterator { + public: + const grpc_mdelem &operator*() const { return *elem_->md; } + const grpc_mdelem *operator->() const { return elem_->md; } + + const_iterator &operator++() { + elem_ = elem_->next; + return *this; + } + const_iterator operator++(int) { + const_iterator tmp(*this); + operator++(); + return tmp; + } + const_iterator &operator--() { + elem_ = elem_->prev; + return *this; + } + const_iterator operator--(int) { + const_iterator tmp(*this); + operator--(); + return tmp; + } + + bool operator==(const const_iterator &other) const { + return elem_ == other.elem_; + } + bool operator!=(const const_iterator &other) const { + return elem_ != other.elem_; + } + + private: + friend class MetadataBatch; + explicit const_iterator(grpc_linked_mdelem *elem) : elem_(elem) {} + + grpc_linked_mdelem *elem_; + }; + + const_iterator begin() const { return const_iterator(batch_->list.head); } + const_iterator end() const { return const_iterator(nullptr); } + + private: + grpc_metadata_batch *batch_; // Not owned. +}; + +/// A C++ wrapper for the \c grpc_transport_op struct. +class TransportOp { + public: + /// Borrows a pointer to \a op, but does NOT take ownership. + /// The caller must ensure that \a op continues to exist for as + /// long as the TransportOp object does. + explicit TransportOp(grpc_transport_op *op) : op_(op) {} + + grpc_transport_op *op() const { return op_; } + + // TODO(roth): Add a C++ wrapper for grpc_error? + grpc_error *disconnect_with_error() const { + return op_->disconnect_with_error; + } + bool send_goaway() const { return op_->send_goaway; } + + // TODO(roth): Add methods for additional fields as needed. + + private: + grpc_transport_op *op_; // Not owned. +}; + +/// A C++ wrapper for the \c grpc_transport_stream_op struct. +class TransportStreamOp { + public: + /// Borrows a pointer to \a op, but does NOT take ownership. + /// The caller must ensure that \a op continues to exist for as + /// long as the TransportStreamOp object does. + explicit TransportStreamOp(grpc_transport_stream_op *op) + : op_(op), + send_initial_metadata_(op->send_initial_metadata), + send_trailing_metadata_(op->send_trailing_metadata), + recv_initial_metadata_(op->recv_initial_metadata), + recv_trailing_metadata_(op->recv_trailing_metadata) {} + + grpc_transport_stream_op *op() const { return op_; } + + grpc_closure *on_complete() const { return op_->on_complete; } + void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; } + + MetadataBatch *send_initial_metadata() { + return op_->send_initial_metadata == nullptr ? nullptr + : &send_initial_metadata_; + } + MetadataBatch *send_trailing_metadata() { + return op_->send_trailing_metadata == nullptr ? nullptr + : &send_trailing_metadata_; + } + MetadataBatch *recv_initial_metadata() { + return op_->recv_initial_metadata == nullptr ? nullptr + : &recv_initial_metadata_; + } + MetadataBatch *recv_trailing_metadata() { + return op_->recv_trailing_metadata == nullptr ? nullptr + : &recv_trailing_metadata_; + } + + uint32_t *send_initial_metadata_flags() const { + return &op_->send_initial_metadata_flags; + } + + grpc_closure *recv_initial_metadata_ready() const { + return op_->recv_initial_metadata_ready; + } + void set_recv_initial_metadata_ready(grpc_closure *closure) { + op_->recv_initial_metadata_ready = closure; + } + + grpc_byte_stream *send_message() const { return op_->send_message; } + void set_send_message(grpc_byte_stream *send_message) { + op_->send_message = send_message; + } + + /// To be called only on clients and servers, respectively. + grpc_client_security_context *client_security_context() const { + return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; + } + grpc_server_security_context *server_security_context() const { + return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; + } + + census_context *get_census_context() const { + return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value; + } + + private: + grpc_transport_stream_op *op_; // Not owned. + MetadataBatch send_initial_metadata_; + MetadataBatch send_trailing_metadata_; + MetadataBatch recv_initial_metadata_; + MetadataBatch recv_trailing_metadata_; +}; + +/// Represents channel data. +class ChannelData { + public: + virtual ~ChannelData() { + if (peer_) gpr_free((void *)peer_); + } + + /// Caller does NOT take ownership of result. + const char *peer() const { return peer_; } + + // TODO(roth): Find a way to avoid passing elem into these methods. + virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, TransportOp *op); + + protected: + /// Takes ownership of \a peer. + ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} + + private: + const char *peer_; +}; + +/// Represents call data. +class CallData { + public: + virtual ~CallData() {} + + /// Initializes the call data. + virtual grpc_error *Init() { return GRPC_ERROR_NONE; } + + // TODO(roth): Find a way to avoid passing elem into these methods. + + /// Starts a new stream operation. + virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + TransportStreamOp *op); + + /// Sets a pollset or pollset set. + virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent); + + /// Gets the peer name. + virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + + protected: + explicit CallData(const ChannelData &) {} +}; + +namespace internal { + +// Defines static members for passing to C core. +// Members of this class correspond to the members of the C +// grpc_channel_filter struct. +template +class ChannelFilter GRPC_FINAL { + public: + static const size_t channel_data_size = sizeof(ChannelDataType); + + static void InitChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + const char *peer = + args->optional_transport + ? grpc_transport_get_peer(exec_ctx, args->optional_transport) + : nullptr; + // Construct the object in the already-allocated memory. + new (elem->channel_data) ChannelDataType(*args->channel_args, peer); + } + + static void DestroyChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + reinterpret_cast(elem->channel_data)->~ChannelDataType(); + } + + static void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data; + TransportOp op_wrapper(op); + channel_data->StartTransportOp(exec_ctx, elem, &op_wrapper); + } + + static const size_t call_data_size = sizeof(CallDataType); + + static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + const ChannelDataType &channel_data = + *(ChannelDataType *)elem->channel_data; + // Construct the object in the already-allocated memory. + CallDataType *call_data = new (elem->call_data) CallDataType(channel_data); + return call_data->Init(); + } + + static void DestroyCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + const grpc_call_final_info *final_info, + void *and_free_memory) { + reinterpret_cast(elem->call_data)->~CallDataType(); + } + + static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + CallDataType *call_data = (CallDataType *)elem->call_data; + TransportStreamOp op_wrapper(op); + call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper); + } + + static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { + CallDataType *call_data = (CallDataType *)elem->call_data; + call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent); + } + + static char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + CallDataType *call_data = (CallDataType *)elem->call_data; + return call_data->GetPeer(exec_ctx, elem); + } +}; + +struct FilterRecord { + grpc_channel_stack_type stack_type; + int priority; + std::function include_filter; + grpc_channel_filter filter; +}; +extern std::vector *channel_filters; + +void ChannelFilterPluginInit(); +void ChannelFilterPluginShutdown(); + +} // namespace internal + +/// Registers a new filter. +/// Must be called by only one thread at a time. +/// The \a include_filter argument specifies a function that will be called +/// to determine at run-time whether or not to add the filter. If the +/// value is nullptr, the filter will be added unconditionally. +template +void RegisterChannelFilter( + const char *name, grpc_channel_stack_type stack_type, int priority, + std::function include_filter) { + // If we haven't been called before, initialize channel_filters and + // call grpc_register_plugin(). + if (internal::channel_filters == nullptr) { + grpc_register_plugin(internal::ChannelFilterPluginInit, + internal::ChannelFilterPluginShutdown); + internal::channel_filters = new std::vector(); + } + // Add an entry to channel_filters. The filter will be added when the + // C-core initialization code calls ChannelFilterPluginInit(). + typedef internal::ChannelFilter FilterType; + internal::FilterRecord filter_record = { + stack_type, + priority, + include_filter, + {FilterType::StartTransportStreamOp, FilterType::StartTransportOp, + FilterType::call_data_size, FilterType::InitCallElement, + FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement, + FilterType::channel_data_size, FilterType::InitChannelElement, + FilterType::DestroyChannelElement, FilterType::GetPeer, name}}; + internal::channel_filters->push_back(filter_record); +} + +} // namespace grpc + +#endif // GRPCXX_CHANNEL_FILTER_H diff --git a/src/cpp/ext/reflection.pb.cc b/src/cpp/ext/reflection.pb.cc index b73a65d0a02..a84494f9a98 100644 --- a/src/cpp/ext/reflection.pb.cc +++ b/src/cpp/ext/reflection.pb.cc @@ -98,6 +98,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection* } // namespace +void protobuf_AssignDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AssignDesc_reflection_2eproto() { protobuf_AddDesc_reflection_2eproto(); const ::google::protobuf::FileDescriptor* file = @@ -253,6 +254,7 @@ inline void protobuf_AssignDescriptorsOnce() { &protobuf_AssignDesc_reflection_2eproto); } +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( @@ -296,6 +298,7 @@ void protobuf_ShutdownFile_reflection_2eproto() { delete ErrorResponse_reflection_; } +void protobuf_AddDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AddDesc_reflection_2eproto() { static bool already_here = false; if (already_here) return; @@ -366,16 +369,6 @@ struct StaticDescriptorInitializer_reflection_2eproto { } } static_descriptor_initializer_reflection_2eproto_; -namespace { - -static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; -static void MergeFromFail(int line) { - GOOGLE_CHECK(false) << __FILE__ << ":" << line; -} - -} // namespace - - // =================================================================== #if !defined(_MSC_VER) || _MSC_VER >= 1900 @@ -684,8 +677,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionRequest) } -::google::protobuf::uint8* ServerReflectionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionRequest) // optional string host = 1; if (this->host().size() > 0) { @@ -723,8 +716,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5; if (has_file_containing_extension()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_request_.file_containing_extension_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_request_.file_containing_extension_, false, target); } // optional string all_extension_numbers_of_type = 6; @@ -812,7 +805,9 @@ int ServerReflectionRequest::ByteSize() const { void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -827,7 +822,9 @@ void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) void ServerReflectionRequest::MergeFrom(const ServerReflectionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_request_case()) { case kFileByFilename: { set_file_by_filename(from.file_by_filename()); @@ -1486,8 +1483,8 @@ void ExtensionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionRequest) } -::google::protobuf::uint8* ExtensionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionRequest) // optional string containing_type = 1; if (this->containing_type().size() > 0) { @@ -1535,7 +1532,9 @@ int ExtensionRequest::ByteSize() const { void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -1550,7 +1549,9 @@ void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { void ExtensionRequest::MergeFrom(const ExtensionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.containing_type().size() > 0) { containing_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.containing_type_); @@ -1937,8 +1938,8 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionResponse) } -::google::protobuf::uint8* ServerReflectionResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionResponse) // optional string valid_host = 1; if (this->valid_host().size() > 0) { @@ -1954,36 +1955,36 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2; if (this->has_original_request()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->original_request_, target); + InternalWriteMessageNoVirtualToArray( + 2, *this->original_request_, false, target); } // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4; if (has_file_descriptor_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, *message_response_.file_descriptor_response_, target); + InternalWriteMessageNoVirtualToArray( + 4, *message_response_.file_descriptor_response_, false, target); } // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5; if (has_all_extension_numbers_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_response_.all_extension_numbers_response_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_response_.all_extension_numbers_response_, false, target); } // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6; if (has_list_services_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, *message_response_.list_services_response_, target); + InternalWriteMessageNoVirtualToArray( + 6, *message_response_.list_services_response_, false, target); } // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7; if (has_error_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, *message_response_.error_response_, target); + InternalWriteMessageNoVirtualToArray( + 7, *message_response_.error_response_, false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServerReflectionResponse) @@ -2049,7 +2050,9 @@ int ServerReflectionResponse::ByteSize() const { void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2064,7 +2067,9 @@ void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from void ServerReflectionResponse::MergeFrom(const ServerReflectionResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_response_case()) { case kFileDescriptorResponse: { mutable_file_descriptor_response()->::grpc::reflection::v1alpha::FileDescriptorResponse::MergeFrom(from.file_descriptor_response()); @@ -2550,8 +2555,8 @@ void FileDescriptorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileDescriptorResponse) } -::google::protobuf::uint8* FileDescriptorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileDescriptorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileDescriptorResponse) // repeated bytes file_descriptor_proto = 1; for (int i = 0; i < this->file_descriptor_proto_size(); i++) { @@ -2582,7 +2587,9 @@ int FileDescriptorResponse::ByteSize() const { void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const FileDescriptorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2597,7 +2604,9 @@ void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) void FileDescriptorResponse::MergeFrom(const FileDescriptorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } file_descriptor_proto_.MergeFrom(from.file_descriptor_proto_); } @@ -2863,8 +2872,8 @@ void ExtensionNumberResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionNumberResponse) } -::google::protobuf::uint8* ExtensionNumberResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionNumberResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionNumberResponse) // optional string base_type_name = 1; if (this->base_type_name().size() > 0) { @@ -2931,7 +2940,9 @@ int ExtensionNumberResponse::ByteSize() const { void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionNumberResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2946,7 +2957,9 @@ void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) void ExtensionNumberResponse::MergeFrom(const ExtensionNumberResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } extension_number_.MergeFrom(from.extension_number_); if (from.base_type_name().size() > 0) { @@ -3199,14 +3212,14 @@ void ListServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ListServiceResponse) } -::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ListServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ListServiceResponse) // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1; for (unsigned int i = 0, n = this->service_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->service(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->service(i), false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ListServiceResponse) @@ -3233,7 +3246,9 @@ int ListServiceResponse::ByteSize() const { void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ListServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3248,7 +3263,9 @@ void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ListServiceResponse::MergeFrom(const ListServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } service_.MergeFrom(from.service_); } @@ -3459,8 +3476,8 @@ void ServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServiceResponse) } -::google::protobuf::uint8* ServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServiceResponse) // optional string name = 1; if (this->name().size() > 0) { @@ -3496,7 +3513,9 @@ int ServiceResponse::ByteSize() const { void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3511,7 +3530,9 @@ void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ServiceResponse::MergeFrom(const ServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.name().size() > 0) { name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); @@ -3762,8 +3783,8 @@ void ErrorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ErrorResponse) } -::google::protobuf::uint8* ErrorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ErrorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ErrorResponse) // optional int32 error_code = 1; if (this->error_code() != 0) { @@ -3811,7 +3832,9 @@ int ErrorResponse::ByteSize() const { void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ErrorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3826,7 +3849,9 @@ void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { void ErrorResponse::MergeFrom(const ErrorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.error_code() != 0) { set_error_code(from.error_code()); } diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index f6c226567d9..d99bf8e4e19 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -40,7 +40,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -108,4 +108,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config index 6a930c17ee6..456ffcd8d02 100644 --- a/src/csharp/Grpc.Core.Tests/packages.config +++ b/src/csharp/Grpc.Core.Tests/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 1952ee37121..622813fb381 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -40,7 +40,7 @@ - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -152,4 +152,4 @@ roots.pem - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index 543549eb2d2..a8459c4d9cd 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -15,7 +15,7 @@ Copyright 2015, Google Inc. gRPC RPC Protocol HTTP/2 - + diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config index 80daf048d0b..65147740217 100644 --- a/src/csharp/Grpc.Core/packages.config +++ b/src/csharp/Grpc.Core/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 901b0ce5d03..f7e21a25dda 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -31,7 +31,7 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index ad319478ab0..764a335ddfb 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -42,11 +42,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index ad319478ab0..764a335ddfb 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -42,11 +42,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.Examples": { diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 4c7d89309af..c8801a94131 100644 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -43,7 +43,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -75,4 +75,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config index 668601af8e7..cc473eb34c1 100644 --- a/src/csharp/Grpc.Examples.Tests/packages.config +++ b/src/csharp/Grpc.Examples.Tests/packages.config @@ -1,7 +1,7 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 3dfa84e896e..4521649b6fa 100644 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -48,7 +48,7 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -72,4 +72,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config index a70dcbd4c68..8985ae4c772 100644 --- a/src/csharp/Grpc.Examples/packages.config +++ b/src/csharp/Grpc.Examples/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 48ec530abb1..5329f390e4e 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -1,6 +1,11 @@ { "buildOptions": { }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.Core": { diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 7db8b2d38e2..e13416cc1a5 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -46,7 +46,7 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -82,4 +82,4 @@ --> - \ No newline at end of file + diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec index 7b3b391009e..4ffd18ccb21 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec @@ -16,7 +16,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config index a52d9e508ff..063094f7757 100644 --- a/src/csharp/Grpc.HealthCheck/packages.config +++ b/src/csharp/Grpc.HealthCheck/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 287950720fe..9afcb306b40 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -44,11 +44,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.IntegrationTesting": { diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 287950720fe..9afcb306b40 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -44,11 +44,6 @@ } } }, - "runtimes": { - "win7-x64": { }, - "debian.8-x64": { }, - "osx.10.11-x64": { } - }, "dependencies": { "Grpc.IntegrationTesting": { diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 3a0764230d6..7512d2a5d11 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -70,7 +70,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -149,4 +149,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config index 3161c5b7557..e6e64e65581 100644 --- a/src/csharp/Grpc.IntegrationTesting/packages.config +++ b/src/csharp/Grpc.IntegrationTesting/packages.config @@ -5,7 +5,7 @@ - + diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js index 043df06a669..51ff1da01ec 100644 --- a/src/node/src/credentials.js +++ b/src/node/src/credentials.js @@ -71,6 +71,8 @@ var Metadata = require('./metadata.js'); var common = require('./common.js'); +var _ = require('lodash'); + /** * Create an SSL Credentials object. If using a client-side certificate, both * the second and third arguments must be passed. @@ -99,7 +101,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) { var message = ''; if (error) { message = error.message; - if (error.hasOwnProperty('code')) { + if (error.hasOwnProperty('code') && _.isFinite(error.code)) { code = error.code; } else { code = grpc.status.UNAUTHENTICATED; diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js index 0a21572582e..305843f665e 100644 --- a/src/node/test/credentials_test.js +++ b/src/node/test/credentials_test.js @@ -71,7 +71,10 @@ var fakeSuccessfulGoogleCredentials = { var fakeFailingGoogleCredentials = { getRequestMetadata: function(service_url, callback) { setTimeout(function() { - callback(new Error('Authentication failure')); + // Google credentials currently adds string error codes to auth errors + var error = new Error('Authentication failure'); + error.code = 'ENOENT'; + callback(error); }, 0); } }; diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 97f4f586b72..07d62d20479 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -37,7 +37,7 @@ Pod::Spec.new do |s| # before them. s.name = '!ProtoCompiler-gRPCPlugin' v = '1.0.0-pre1' - s.version = v + s.version = "#{v}.2" # .2 to depend on protoc 3.0.0 s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use @@ -96,7 +96,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.0.0-beta-3.1' + s.dependency '!ProtoCompiler', '3.0.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 56aacc33305..5018dedc066 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.0.0-beta-3.1' + v = '3.0.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC @@ -108,7 +108,7 @@ Pod::Spec.new do |s| 'google/**/*.proto' # Well-known protobuf types # Restrict the protobuf runtime version to the one supported by this version of protoc. - s.dependency 'Protobuf', v + s.dependency 'Protobuf', '~> 3.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' @@ -120,7 +120,7 @@ Pod::Spec.new do |s| repo_root = '../..' plugin = 'grpc_objective_c_plugin' s.prepare_command = <<-CMD - if [ ! -f protoc ]; then + if [ ! -f bin/protoc ]; then cd #{repo_root} # This will build protoc from the Protobuf submodule of gRPC, and put it in # #{repo_root}/bins/opt/protobuf. @@ -129,7 +129,9 @@ Pod::Spec.new do |s| # _we do not want_. Find a way for this to always build from source. make #{plugin} cd - + else + mv bin/protoc . + mv include/google . fi CMD - end diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 6e917ddd813..909b12bab2d 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,7 +48,7 @@ Pod::Spec.new do |s| src = '.' # We'll use protoc with the gRPC plugin. - s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1' + s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1.2' # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = '/Pods' diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 7222a80b887..974a6765c70 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index e7bab137620..66d4fa9412c 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -91,7 +91,7 @@ class ViewController: UIViewController { call.startWithWriteable(GRXWriteable { response, error in if let response = response as? NSData { - NSLog("3. Received response:\n\(RMTSimpleResponse(data: response, error: nil))") + NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))") } else { NSLog("3. Finished with error: \(error!)") } diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 53ba1019131..3d28234fa23 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 727d6288853..6074175a449 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -50,6 +50,7 @@ SETUP_REQUIRES = ( ) INSTALL_REQUIRES = ( + 'protobuf>=3.0.0', 'grpcio>=0.15.0', ) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 0afaf7dfa21..5c60eaca3a3 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -63,7 +63,7 @@ INSTALL_REQUIRES = ( 'grpcio>=0.14.0', 'grpcio-health-checking>=0.14.0', 'oauth2client>=1.4.7', - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', 'six>=1.10', ) diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 3c00f686cec..9cae96a00d8 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -32,12 +32,12 @@ import threading import time import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool def _ready_in_connectivities(connectivities): @@ -104,7 +104,8 @@ class ChannelConnectivityTest(unittest.TestCase): grpc.ChannelConnectivity.READY, fifth_connectivities) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() first_callback = _Callback() @@ -141,9 +142,11 @@ class ChannelConnectivityTest(unittest.TestCase): fourth_connectivities) self.assertNotIn( grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities) + self.assertFalse(thread_pool.was_used()) def test_reachable_then_unreachable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() callback = _Callback() @@ -155,6 +158,7 @@ class ChannelConnectivityTest(unittest.TestCase): server.stop(None) callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready) channel.unsubscribe(callback.update) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index e8982ed2ded..24f5b45b18e 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -31,12 +31,12 @@ import threading import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool class _Callback(object): @@ -78,7 +78,8 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.running()) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() channel = grpc.insecure_channel('localhost:{}'.format(port)) @@ -97,6 +98,7 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.cancelled()) self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/_thread_pool.py new file mode 100644 index 00000000000..f13cc2f86fc --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_thread_pool.py @@ -0,0 +1,48 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import threading +from concurrent import futures + + +class RecordingThreadPool(futures.Executor): + """A thread pool that records if used.""" + def __init__(self, max_workers): + self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers) + self._lock = threading.Lock() + self._was_used = False + + def submit(self, fn, *args, **kwargs): + with self._lock: + self._was_used = True + self._tp_executor.submit(fn, *args, **kwargs) + + def was_used(self): + with self._lock: + return self._was_used diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template index bd0e8b2c138..e6f8290200e 100644 --- a/templates/src/csharp/Grpc.Core/project.json.template +++ b/templates/src/csharp/Grpc.Core/project.json.template @@ -33,7 +33,7 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index 67151dbcfa8..51c5e85c66d 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True"/> + <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index 67151dbcfa8..51c5e85c66d 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True"/> + <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/> "dependencies": { "Grpc.Examples": { "target": "project" diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index 93151f2b89e..af1ee425096 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True"/> + <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index 93151f2b89e..af1ee425096 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -1,7 +1,7 @@ %YAML 1.2 --- | { - <%include file="../build_options.include" args="executable=True,includeData=True"/> + <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/> "dependencies": { "Grpc.IntegrationTesting": { "target": "project" diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include index 169a45a808a..a200897e0f2 100644 --- a/templates/src/csharp/build_options.include +++ b/templates/src/csharp/build_options.include @@ -1,4 +1,4 @@ -<%page args="executable=False,includeData=False"/>\ +<%page args="executable=False,includeData=False,includeRuntimes=True"/>\ "buildOptions": { % if executable: "emitEntryPoint": true @@ -51,6 +51,8 @@ } } }, + %endif + % if includeRuntimes: "runtimes": { "win7-x64": { }, "debian.8-x64": { }, diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 489dc44a436..7e89dec2cc2 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -14,3 +14,5 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} ca-certificates-mono ${'\\'} nuget ${'\\'} && apt-get clean + +RUN nuget update -self diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc new file mode 100644 index 00000000000..853720fd0d0 --- /dev/null +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -0,0 +1,353 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/cpp/common/channel_filter.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/byte_buffer_proto_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +void* tag(int i) { return (void*)(intptr_t)i; } + +void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { + bool ok; + void* got_tag; + EXPECT_TRUE(cq->Next(&got_tag, &ok)); + EXPECT_EQ(expect_ok, ok); + EXPECT_EQ(tag(i), got_tag); +} + +namespace { + +int global_num_connections = 0; +int global_num_calls = 0; +mutex global_mu; + +void IncrementConnectionCounter() { + unique_lock lock(global_mu); + ++global_num_connections; +} + +void ResetConnectionCounter() { + unique_lock lock(global_mu); + global_num_connections = 0; +} + +int GetConnectionCounterValue() { + unique_lock lock(global_mu); + return global_num_connections; +} + +void IncrementCallCounter() { + unique_lock lock(global_mu); + ++global_num_calls; +} + +void ResetCallCounter() { + unique_lock lock(global_mu); + global_num_calls = 0; +} + +int GetCallCounterValue() { + unique_lock lock(global_mu); + return global_num_calls; +} + +} // namespace + +class ChannelDataImpl : public ChannelData { + public: + ChannelDataImpl(const grpc_channel_args& args, const char* peer) + : ChannelData(args, peer) { + IncrementConnectionCounter(); + } +}; + +class CallDataImpl : public CallData { + public: + explicit CallDataImpl(const ChannelDataImpl& channel_data) + : CallData(channel_data) {} + + void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, + TransportStreamOp* op) GRPC_OVERRIDE { + // Incrementing the counter could be done from the ctor, but we want + // to test that the individual methods are actually called correctly. + if (op->recv_initial_metadata() != nullptr) IncrementCallCounter(); + grpc_call_next_op(exec_ctx, elem, op->op()); + } +}; + +class FilterEnd2endTest : public ::testing::Test { + protected: + FilterEnd2endTest() : server_host_("localhost") {} + + void SetUp() GRPC_OVERRIDE { + int port = grpc_pick_unused_port_or_die(); + server_address_ << server_host_ << ":" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterAsyncGenericService(&generic_service_); + srv_cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cli_cq_.Shutdown(); + srv_cq_->Shutdown(); + while (cli_cq_.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq_->Next(&ignored_tag, &ignored_ok)) + ; + } + + void ResetStub() { + std::shared_ptr channel = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + generic_stub_.reset(new GenericStub(channel)); + ResetConnectionCounter(); + ResetCallCounter(); + } + + void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } + void client_ok(int i) { verify_ok(&cli_cq_, i, true); } + void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); } + void client_fail(int i) { verify_ok(&cli_cq_, i, false); } + + void SendRpc(int num_rpcs) { + const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter stream(&srv_ctx); + + // The string needs to be long enough to test heap-based slice. + send_request.set_message("Hello world. Hello world. Hello world."); + std::unique_ptr call = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + call->Write(*send_buffer, tag(2)); + // Send ByteBuffer can be destroyed after calling Write. + send_buffer.reset(); + client_ok(2); + call->WritesDone(tag(3)); + client_ok(3); + + generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), + srv_cq_.get(), tag(4)); + + verify_ok(srv_cq_.get(), 4, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + ByteBuffer recv_buffer; + stream.Read(&recv_buffer, tag(5)); + server_ok(5); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + stream.Write(*send_buffer, tag(6)); + send_buffer.reset(); + server_ok(6); + + stream.Finish(Status::OK, tag(7)); + server_ok(7); + + recv_buffer.Clear(); + call->Read(&recv_buffer, tag(8)); + client_ok(8); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + + call->Finish(&recv_status, tag(9)); + client_ok(9); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + } + } + + CompletionQueue cli_cq_; + std::unique_ptr srv_cq_; + std::unique_ptr stub_; + std::unique_ptr generic_stub_; + std::unique_ptr server_; + AsyncGenericService generic_service_; + const grpc::string server_host_; + std::ostringstream server_address_; +}; + +TEST_F(FilterEnd2endTest, SimpleRpc) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + SendRpc(1); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(1, GetCallCounterValue()); +} + +TEST_F(FilterEnd2endTest, SequentialRpcs) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + SendRpc(10); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(10, GetCallCounterValue()); +} + +// One ping, one pong. +TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + + const grpc::string kMethodName( + "/grpc.cpp.test.util.EchoTestService/BidiStream"); + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter srv_stream(&srv_ctx); + + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + send_request.set_message("Hello"); + std::unique_ptr cli_stream = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + + generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(), + srv_cq_.get(), tag(2)); + + verify_ok(srv_cq_.get(), 2, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + cli_stream->Write(*send_buffer, tag(3)); + send_buffer.reset(); + client_ok(3); + + ByteBuffer recv_buffer; + srv_stream.Read(&recv_buffer, tag(4)); + server_ok(4); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + srv_stream.Write(*send_buffer, tag(5)); + send_buffer.reset(); + server_ok(5); + + cli_stream->Read(&recv_buffer, tag(6)); + client_ok(6); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + EXPECT_EQ(send_response.message(), recv_response.message()); + + cli_stream->WritesDone(tag(7)); + client_ok(7); + + srv_stream.Read(&recv_buffer, tag(8)); + server_fail(8); + + srv_stream.Finish(Status::OK, tag(9)); + server_ok(9); + + cli_stream->Finish(&recv_status, tag(10)); + client_ok(10); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + + EXPECT_EQ(1, GetCallCounterValue()); + EXPECT_EQ(1, GetConnectionCounterValue()); +} + +void RegisterFilter() { + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::RegisterFilter(); + return RUN_ALL_TESTS(); +} diff --git a/third_party/protobuf b/third_party/protobuf index bdeb215cab2..e8ae137c964 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit bdeb215cab2985195325fcd5e70c3fa751f46e0f +Subproject commit e8ae137c96444ea313485ed1118c5e43b2099cf1 diff --git a/tools/codegen/extensions/gen_reflection_proto.sh b/tools/codegen/extensions/gen_reflection_proto.sh index 45a1a9f4ec1..bd8aac6a7b1 100755 --- a/tools/codegen/extensions/gen_reflection_proto.sh +++ b/tools/codegen/extensions/gen_reflection_proto.sh @@ -36,7 +36,7 @@ SRC_DIR="src/cpp/ext" INCLUDE_DIR="grpc++/ext" TMP_DIR="tmp" GRPC_PLUGIN="bins/opt/grpc_cpp_plugin" -PROTOC=third_party/protobuf/src/protoc +PROTOC="bins/opt/protobuf/protoc" set -e diff --git a/tools/distrib/check_generated_pb_files.sh b/tools/distrib/check_generated_pb_files.sh index 557067883c5..6b93895484c 100755 --- a/tools/distrib/check_generated_pb_files.sh +++ b/tools/distrib/check_generated_pb_files.sh @@ -38,3 +38,6 @@ docker build -t grpc_check_generated_pb_files tools/dockerfile/grpc_check_genera # run check_pb_files against the checked out codebase docker run -e TEST=$TEST --rm=true -v ${HOST_GIT_ROOT:-`pwd`}:/var/local/jenkins/grpc -t grpc_check_generated_pb_files /var/local/jenkins/grpc/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh + +# If the test fails, please make sure your protobuf submodule is up-to-date and run +# tools/codegen/extensions/gen_reflection_proto.sh to update the generated files. diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index bb1f1cf085b..e8105992dc2 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -177,7 +177,7 @@ setuptools.setup( packages=setuptools.find_packages('.'), namespace_packages=['grpc'], install_requires=[ - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', 'grpcio>=0.15.0', ], package_data=package_data(), diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index e3d52f0cb53..087cc4e2bb4 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -95,6 +95,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ diff --git a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh index e8915493422..1fd088322cd 100755 --- a/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_go/build_interop.sh @@ -46,6 +46,7 @@ go get github.com/golang/protobuf/proto go get golang.org/x/net/context go get golang.org/x/net/trace go get golang.org/x/oauth2 +go get golang.org/x/oauth2/google go get google.golang.org/cloud # Build the interop client and server diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile index 81e3fdc3804..328825392b7 100644 --- a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile +++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/Dockerfile @@ -112,5 +112,7 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile index 25c6fe6ec6a..49218151901 100644 --- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile @@ -95,6 +95,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile index e3d52f0cb53..087cc4e2bb4 100644 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile @@ -95,6 +95,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + # Prepare ccache RUN ln -s /usr/bin/ccache /usr/local/bin/gcc RUN ln -s /usr/bin/ccache /usr/local/bin/g++ diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile index 13f7c10f92f..2540b52ec8f 100644 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile @@ -80,6 +80,8 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ nuget \ && apt-get clean +RUN nuget update -self + #================= # C++ dependencies RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 945298b964c..95c0e853c24 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -863,6 +863,7 @@ src/cpp/client/secure_credentials.h \ src/cpp/common/secure_auth_context.h \ src/cpp/server/secure_server_credentials.h \ src/cpp/client/create_channel_internal.h \ +src/cpp/common/channel_filter.h \ src/cpp/server/dynamic_thread_pool.h \ src/cpp/server/thread_pool_interface.h \ src/cpp/client/secure_credentials.cc \ @@ -880,6 +881,7 @@ src/cpp/client/credentials.cc \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ +src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 542415d9085..9e6ba380f1e 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -701,14 +701,16 @@ class ObjCLanguage(object): _check_compiler(self.args.compiler, ['default']) def test_specs(self): - return [self.config.job_spec(['src/objective-c/tests/run_tests.sh'], - timeout_seconds=None, - shortname='objc-tests', - environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec(['src/objective-c/tests/build_example_test.sh'], - timeout_seconds=15*60, - shortname='objc-examples-build', - environ=_FORCE_ENVIRON_FOR_WRAPPERS)] + return [ + self.config.job_spec(['src/objective-c/tests/run_tests.sh'], + timeout_seconds=None, + shortname='objc-tests', + environ=_FORCE_ENVIRON_FOR_WRAPPERS), + self.config.job_spec(['src/objective-c/tests/build_example_test.sh'], + timeout_seconds=30*60, + shortname='objc-examples-build', + environ=_FORCE_ENVIRON_FOR_WRAPPERS), + ] def pre_build_steps(self): return [] diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index b602d695649..04123ee5d8a 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -45,7 +45,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f) c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0) f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) - bdeb215cab2985195325fcd5e70c3fa751f46e0f third_party/protobuf (v3.0.0-beta-3.3) + e8ae137c96444ea313485ed1118c5e43b2099cf1 third_party/protobuf (v3.0.0-beta-4-74-ge8ae137) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) EOF diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 934604c4024..1206f9821c7 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2137,6 +2137,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "language": "c++", + "name": "filter_end2end_test", + "src": [ + "test/cpp/end2end/filter_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -4245,7 +4263,6 @@ "gpr", "grpc_base", "grpc_lb_policy_grpclb", - "grpc_lb_policy_grpclb", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", "grpc_load_reporting", @@ -4341,7 +4358,6 @@ "gpr", "grpc_base", "grpc_lb_policy_grpclb", - "grpc_lb_policy_grpclb", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", "grpc_load_reporting", @@ -6668,6 +6684,7 @@ "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h" ], @@ -6731,6 +6748,8 @@ "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", + "src/cpp/common/channel_filter.h", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 60032304d9e..5ed13199172 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2290,6 +2290,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "filter_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index cb9e41ea22f..835e2527c99 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -363,6 +363,7 @@ + @@ -397,6 +398,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index a9051182b3c..883e66e1dfd 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -46,6 +46,9 @@ src\cpp\common + + src\cpp\common + src\cpp\common @@ -413,6 +416,9 @@ src\cpp\client + + src\cpp\common + src\cpp\server diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 03be485b297..e71180feb05 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -359,6 +359,7 @@ + @@ -383,6 +384,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index ba99bc53c8c..a9aa147e56d 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -31,6 +31,9 @@ src\cpp\common + + src\cpp\common + src\cpp\common @@ -386,6 +389,9 @@ src\cpp\client + + src\cpp\common + src\cpp\server diff --git a/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj new file mode 100644 index 00000000000..99c000e4fa9 --- /dev/null +++ b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj @@ -0,0 +1,207 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1D42975A-18A5-09D0-30B1-2AE6A97FB9DE} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + filter_end2end_test + static + Debug + static + Debug + + + filter_end2end_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {0BE77741-552A-929B-A497-4EF7ECE17A64} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters new file mode 100644 index 00000000000..c68442365c5 --- /dev/null +++ b/vsprojects/vcxproj/test/filter_end2end_test/filter_end2end_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\cpp\end2end + + + + + + {f7581160-220d-1118-f29e-6b37e45671c9} + + + {63784d35-03cc-1a7e-0c95-a9451bc1daf4} + + + {d2a01682-970e-d23d-1eb8-ef020e3a1ca3} + + + +