Skip to content
Snippets Groups Projects
Commit 04599e1d authored by Michael Davis's avatar Michael Davis
Browse files

Adds XrdSsi + protobuf3 proof of concept code for CTA front-end

parent cae2e4f3
No related branches found
No related tags found
No related merge requests found
CPPFLAGS=-I/usr/include/protobuf3 -std=c++1y -pedantic -Wall -Wextra -Werror -Wno-unused-parameter
LDFLAGS=-L/usr/lib64/protobuf3
LINK.o=$(LINK.cc)
all: test_client
LDLIBS=-lprotobuf
test_client: test.pb.o test_client.o
test_client.o: test_client.cpp test.pb.h
test.pb.h: test.pb.cc
test.pb.cc: test.proto protoc-gen-XrdSsi
#protoc3 --cpp_out=. --plugin=protoc-gen-XrdSsi=./protoc-gen-XrdSsi --XrdSsi_out=. test.proto
protoc3 --cpp_out=. test.proto
LDLIBS=-lprotobuf -lprotoc
protoc-gen-XrdSsi: protoc-gen-XrdSsi.cpp
clean:
rm -f test.pb.h test.pb.cc test.pb.o test.xrdssi.pb.h test.xrdssi.pb.cc test.xrdssi.pb.o test_client test_client.o protoc-gen-XrdSsi
#include <iostream> // just for debug output
#include <memory>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/zero_copy_stream.h>
// Strip .proto from filenames
void strip_proto(std::string &filename)
{
using namespace std;
auto truncate = filename.find(".proto", filename.length()-6);
if(truncate != string::npos)
{
filename.resize(truncate);
}
}
// Google protocol buffer code generator for XRootD SSI service
class XrdSsiGenerator : public google::protobuf::compiler::CodeGenerator
{
public:
XrdSsiGenerator() {}
virtual ~XrdSsiGenerator() {}
virtual bool Generate(const google::protobuf::FileDescriptor *file,
const std::string &parameter,
google::protobuf::compiler::GeneratorContext *generator_context,
std::string *error) const;
#if 0
private:
// Insert the given code into the given file at the given insertion point.
void Insert(grpc::protobuf::compiler::GeneratorContext *context,
const grpc::string &filename, const grpc::string &insertion_point,
const grpc::string &code) const {
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
}
#endif
};
bool XrdSsiGenerator::Generate(const google::protobuf::FileDescriptor *file,
const std::string &parameter,
google::protobuf::compiler::GeneratorContext *generator_context,
std::string *error) const
{
using namespace std;
// Ensure that generic services is disabled in the .proto file
if (file->options().cc_generic_services())
{
*error = "XrdSsi proto compiler plugin does not work with generic services: set cc_generic_services = false.";
return false;
}
// Create the output files
string filename_base = file->name();
strip_proto(filename_base);
unique_ptr<google::protobuf::io::ZeroCopyOutputStream> header_output(generator_context->Open(filename_base + ".xrdssi.pb.h"));
void *data;
int bufsize;
header_output->Next(&data, &bufsize);
strcpy(reinterpret_cast<char*>(data), "Hello, world!");
return true;
}
#if 0
{
grpc_cpp_generator::Parameters generator_parameters;
generator_parameters.use_system_headers = true;
generator_parameters.generate_mock_code = false;
ProtoBufFile pbfile(file);
if (!parameter.empty()) {
std::vector<grpc::string> parameters_list =
grpc_generator::tokenize(parameter, ",");
for (auto parameter_string = parameters_list.begin();
parameter_string != parameters_list.end(); parameter_string++) {
std::vector<grpc::string> param =
grpc_generator::tokenize(*parameter_string, "=");
if (param[0] == "services_namespace") {
generator_parameters.services_namespace = param[1];
} else if (param[0] == "use_system_headers") {
if (param[1] == "true") {
generator_parameters.use_system_headers = true;
} else if (param[1] == "false") {
generator_parameters.use_system_headers = false;
} else {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else if (param[0] == "grpc_search_path") {
generator_parameters.grpc_search_path = param[1];
} else if (param[0] == "generate_mock_code") {
if (param[1] == "true") {
generator_parameters.generate_mock_code = true;
} else if (param[1] != "false") {
*error = grpc::string("Invalid parameter: ") + *parameter_string;
return false;
}
} else {
*error = grpc::string("Unknown parameter: ") + *parameter_string;
return false;
}
}
}
grpc::string file_name = grpc_generator::StripProto(file->name());
grpc::string header_code =
grpc_cpp_generator::GetHeaderPrologue(&pbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderIncludes(&pbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderServices(&pbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output(
context->Open(file_name + ".grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream header_coded_out(header_output.get());
header_coded_out.WriteRaw(header_code.data(), header_code.size());
grpc::string source_code =
grpc_cpp_generator::GetSourcePrologue(&pbfile, generator_parameters) +
grpc_cpp_generator::GetSourceIncludes(&pbfile, generator_parameters) +
grpc_cpp_generator::GetSourceServices(&pbfile, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output(
context->Open(file_name + ".grpc.pb.cc"));
grpc::protobuf::io::CodedOutputStream source_coded_out(source_output.get());
source_coded_out.WriteRaw(source_code.data(), source_code.size());
if (!generator_parameters.generate_mock_code) {
return true;
}
grpc::string mock_code =
grpc_cpp_generator::GetMockPrologue(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockIncludes(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockServices(&pbfile, generator_parameters) +
grpc_cpp_generator::GetMockEpilogue(&pbfile, generator_parameters);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> mock_output(
context->Open(file_name + "_mock.grpc.pb.h"));
grpc::protobuf::io::CodedOutputStream mock_coded_out(mock_output.get());
mock_coded_out.WriteRaw(mock_code.data(), mock_code.size());
return true;
}
#endif
int main(int argc, char* argv[])
{
XrdSsiGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}
syntax = "proto3";
option cc_generic_services = false; //< Generic services are deprecated
package eos.wfe;
// XRootD SSI Request
message Request {
string message_text = 1; //< Text of the request
}
// XRootD SSI Response
message Response {
string message_text = 1; //< Response text on success
}
message Error {
enum Source { SOURCE_NONE = 0; USER_ERROR = 1; CTA_ERROR = 2; CTA_TIMEOUT = 3; }
enum Audience { AUDIENCE_NONE = 0; EOS_LOG = 1; END_USER = 2; }
Source source = 1; //< The source of the error
bool retry = 2; //< Whether to retry in case of failure
Audience audience = 3; //< The intended audience of the error message
string text = 4; //< Empty on success, otherwise an error message
}
message Result {
uint32 result_code = 1; //< Zero on success, non-zero on error
oneof response_or_error {
Response response = 2; //< Response in case of success
Error error = 3; //< Error in case of failure
}
}
// XRootD SSI Service
service XrdSsiService {
rpc SendRequest(Request) returns(Result);
}
#include <iostream>
#include <google/protobuf/util/json_util.h> // for Json output
#include "test.pb.h"
int main(int argc, char *argv[])
{
using namespace std;
// Verify that the version of the library that we linked against is compatible with the version of
// the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
eos::wfe::Request request;
request.set_message_text("Archive some file");
// Output message in Json format
google::protobuf::util::JsonPrintOptions options;
options.add_whitespace = true;
options.always_print_primitive_fields = true;
string jsonNotification;
google::protobuf::util::MessageToJsonString(request, &jsonNotification, options);
cout << "Sending message:" << endl << jsonNotification;
// Optional: Delete all global objects allocated by libprotobuf
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment