diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h
index 071c5f695c5..6c931ad28ae 100644
--- a/src/core/lib/channel/context.h
+++ b/src/core/lib/channel/context.h
@@ -47,6 +47,9 @@ typedef enum {
/// Value is a \a census_context.
GRPC_CONTEXT_TRACING,
+ /// Reserved for traffic_class_context.
+ GRPC_CONTEXT_TRAFFIC,
+
GRPC_CONTEXT_COUNT
} grpc_context_index;
diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 7407f646d16..5255e4c4036 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,4 +1,4 @@
include grpc_version.py
include health_commands.py
-graft grpc
+graft grpc_health
global-exclude *.pyc
diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc
index a3da5682dc2..b9900ca1b7a 100644
--- a/test/cpp/util/grpc_tool.cc
+++ b/test/cpp/util/grpc_tool.cc
@@ -86,11 +86,12 @@ class GrpcTool {
// callback);
// bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback
// callback);
- // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback
- // callback);
- // bool ToText(int argc, const char** argv, GrpcToolOutputCallback callback);
- // bool ToBinary(int argc, const char** argv, GrpcToolOutputCallback
- // callback);
+ bool ParseMessage(int argc, const char** argv, const CliCredentials& cred,
+ GrpcToolOutputCallback callback);
+ bool ToText(int argc, const char** argv, const CliCredentials& cred,
+ GrpcToolOutputCallback callback);
+ bool ToBinary(int argc, const char** argv, const CliCredentials& cred,
+ GrpcToolOutputCallback callback);
void SetPrintCommandMode(int exit_status) {
print_command_usage_ = true;
@@ -173,9 +174,9 @@ const Command ops[] = {
{"list", BindWith5Args(&GrpcTool::ListServices), 1, 3},
{"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3},
{"type", BindWith5Args(&GrpcTool::PrintType), 2, 2},
- // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
- // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
- // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
+ {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
+ {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
+ {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
};
void Usage(const grpc::string& msg) {
@@ -185,9 +186,9 @@ void Usage(const grpc::string& msg) {
" grpc_cli ls ... ; List services\n"
" grpc_cli call ... ; Call method\n"
" grpc_cli type ... ; Print type\n"
- // " grpc_cli parse ... ; Parse message\n"
- // " grpc_cli totext ... ; Convert binary message to text\n"
- // " grpc_cli tobinary ... ; Convert text message to binary\n"
+ " grpc_cli parse ... ; Parse message\n"
+ " grpc_cli totext ... ; Convert binary message to text\n"
+ " grpc_cli tobinary ... ; Convert text message to binary\n"
" grpc_cli help ... ; Print this message, or per-command usage\n"
"\n",
msg.c_str());
@@ -496,5 +497,122 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
return callback(output_ss.str());
}
+bool GrpcTool::ParseMessage(int argc, const char** argv,
+ const CliCredentials& cred,
+ GrpcToolOutputCallback callback) {
+ CommandUsage(
+ "Parse message\n"
+ " grpc_cli parse
[]\n"
+ " ; host:port\n"
+ " ; Protocol buffer type name\n"
+ " ; Text protobuffer (overrides --infile)\n"
+ " --protofiles ; Comma separated proto files used as a"
+ " fallback when parsing request/response\n"
+ " --proto_path ; The search path of proto files, valid"
+ " only when --protofiles is given\n"
+ " --infile ; Input filename (defaults to stdin)\n"
+ " --outfile ; Output filename (defaults to stdout)\n"
+ " --binary_input ; Input in binary format\n"
+ " --binary_output ; Output in binary format\n" +
+ cred.GetCredentialUsage());
+
+ std::stringstream output_ss;
+ grpc::string message_text;
+ grpc::string server_address(argv[0]);
+ grpc::string type_name(argv[1]);
+ std::unique_ptr parser;
+ grpc::string serialized_request_proto;
+
+ if (argc == 3) {
+ message_text = argv[2];
+ if (!FLAGS_infile.empty()) {
+ fprintf(stderr, "warning: message given in argv, ignoring --infile.\n");
+ }
+ } else {
+ std::stringstream input_stream;
+ if (FLAGS_infile.empty()) {
+ if (isatty(STDIN_FILENO)) {
+ fprintf(stderr, "reading request message from stdin...\n");
+ }
+ input_stream << std::cin.rdbuf();
+ } else {
+ std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary);
+ input_stream << input_file.rdbuf();
+ input_file.close();
+ }
+ message_text = input_stream.str();
+ }
+
+ if (!FLAGS_binary_input || !FLAGS_binary_output) {
+ std::shared_ptr channel =
+ grpc::CreateChannel(server_address, cred.GetCredentials());
+ parser.reset(
+ new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr,
+ FLAGS_proto_path, FLAGS_protofiles));
+ if (parser->HasError()) {
+ return false;
+ }
+ }
+
+ if (FLAGS_binary_input) {
+ serialized_request_proto = message_text;
+ } else {
+ serialized_request_proto =
+ parser->GetSerializedProtoFromMessageType(type_name, message_text);
+ if (parser->HasError()) {
+ return false;
+ }
+ }
+
+ if (FLAGS_binary_output) {
+ output_ss << serialized_request_proto;
+ } else {
+ grpc::string output_text = parser->GetTextFormatFromMessageType(
+ type_name, serialized_request_proto);
+ if (parser->HasError()) {
+ return false;
+ }
+ output_ss << output_text << std::endl;
+ }
+
+ return callback(output_ss.str());
+}
+
+bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred,
+ GrpcToolOutputCallback callback) {
+ CommandUsage(
+ "Convert binary message to text\n"
+ " grpc_cli totext \n"
+ " ; Comma separated list of proto files\n"
+ " ; Protocol buffer type name\n"
+ " --proto_path ; The search path of proto files\n"
+ " --infile ; Input filename (defaults to stdin)\n"
+ " --outfile ; Output filename (defaults to stdout)\n");
+
+ FLAGS_protofiles = argv[0];
+ FLAGS_remotedb = false;
+ FLAGS_binary_input = true;
+ FLAGS_binary_output = false;
+ return ParseMessage(argc, argv, cred, callback);
+}
+
+bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred,
+ GrpcToolOutputCallback callback) {
+ CommandUsage(
+ "Convert text message to binary\n"
+ " grpc_cli tobinary []\n"
+ " ; Comma separated list of proto files\n"
+ " ; Protocol buffer type name\n"
+ " --proto_path ; The search path of proto files\n"
+ " --infile ; Input filename (defaults to stdin)\n"
+ " --outfile ; Output filename (defaults to stdout)\n");
+
+ FLAGS_protofiles = argv[0];
+ FLAGS_remotedb = false;
+ FLAGS_binary_input = false;
+ FLAGS_binary_output = true;
+ return ParseMessage(argc, argv, cred, callback);
+}
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
index 1ff8172306f..33ce611a604 100644
--- a/test/cpp/util/grpc_tool_test.cc
+++ b/test/cpp/util/grpc_tool_test.cc
@@ -86,9 +86,18 @@ using grpc::testing::EchoResponse;
" rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
"{}\n"
+#define ECHO_RESPONSE_MESSAGE \
+ "message: \"echo\"\n" \
+ "param {\n" \
+ " host: \"localhost\"\n" \
+ " peer: \"peer\"\n" \
+ "}\n\n"
+
namespace grpc {
namespace testing {
+DECLARE_bool(binary_input);
+DECLARE_bool(binary_output);
DECLARE_bool(l);
namespace {
@@ -338,6 +347,47 @@ TEST_F(GrpcToolTest, CallCommand) {
ShutdownServer();
}
+TEST_F(GrpcToolTest, ParseCommand) {
+ // Test input "grpc_cli parse localhost: grpc.testing.EchoResponse
+ // ECHO_RESPONSE_MESSAGE"
+ std::stringstream output_stream;
+ std::stringstream binary_output_stream;
+
+ const grpc::string server_address = SetUpServer();
+ const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
+ "grpc.testing.EchoResponse", ECHO_RESPONSE_MESSAGE};
+
+ FLAGS_binary_input = false;
+ FLAGS_binary_output = false;
+ EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+ std::bind(PrintStream, &output_stream,
+ std::placeholders::_1)));
+ // Expected output: ECHO_RESPONSE_MESSAGE
+ EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
+
+ // Parse text message to binary message and then parse it back to text message
+ output_stream.str(grpc::string());
+ output_stream.clear();
+ FLAGS_binary_output = true;
+ EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+ std::bind(PrintStream, &output_stream,
+ std::placeholders::_1)));
+ grpc::string binary_data = output_stream.str();
+ output_stream.str(grpc::string());
+ output_stream.clear();
+ argv[4] = binary_data.c_str();
+ FLAGS_binary_input = true;
+ FLAGS_binary_output = false;
+ EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(),
+ std::bind(PrintStream, &output_stream,
+ std::placeholders::_1)));
+
+ // Expected output: ECHO_RESPONSE_MESSAGE
+ EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE));
+
+ ShutdownServer();
+}
+
TEST_F(GrpcToolTest, TooFewArguments) {
// Test input "grpc_cli call Echo"
std::stringstream output_stream;
diff --git a/tools/distrib/python/grpcio_tools/MANIFEST.in b/tools/distrib/python/grpcio_tools/MANIFEST.in
index 7712834d642..11ce367747a 100644
--- a/tools/distrib/python/grpcio_tools/MANIFEST.in
+++ b/tools/distrib/python/grpcio_tools/MANIFEST.in
@@ -2,6 +2,6 @@ include grpc_version.py
include protoc_deps.py
include protoc_lib_deps.py
include README.rst
-graft grpc
+graft grpc_tools
graft grpc_root
graft third_party
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
index 43ec8c2a4c6..31b3331a66f 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py
@@ -49,7 +49,7 @@ def build_package_protos(package_root):
for proto_file in proto_files:
command = [
- 'grpc.tools.protoc',
+ 'grpc_tools.protoc',
'--proto_path={}'.format(inclusion_root),
'--proto_path={}'.format(well_known_protos_include),
'--python_out={}'.format(inclusion_root),
diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
index 7d5892dc4b7..63fddb2f064 100644
--- a/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc_tools/protoc.py
@@ -45,5 +45,5 @@ def main(command_arguments):
return _protoc_compiler.run_main(command_arguments)
if __name__ == '__main__':
- proto_include = pkg_resources.resource_filename('grpc.tools', '_proto')
+ proto_include = pkg_resources.resource_filename('grpc_tools', '_proto')
sys.exit(main(sys.argv + ['-I{}'.format(proto_include)]))
diff --git a/tools/dockerfile/grpc_artifact_protoc/Dockerfile b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
index 1bbc6e021bc..2904a8fa51f 100644
--- a/tools/dockerfile/grpc_artifact_protoc/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
@@ -59,5 +59,11 @@ RUN yum install -y devtoolset-1.1 \
devtoolset-1.1-libstdc++-devel \
devtoolset-1.1-libstdc++-devel.i686 || true
+# Update Git to version >1.7 to allow cloning submodules with --reference arg.
+RUN yum remove -y git
+RUN yum install -y epel-release
+RUN yum install -y https://centos6.iuscommunity.org/ius-release.rpm
+RUN yum install -y git2u
+
# Start in devtoolset environment that uses GCC 4.7
CMD ["scl", "enable", "devtoolset-1.1", "bash"]