diff --git a/frontend/Makefile b/frontend/Makefile index 7ed2459cae4bce2b73a7585caee544aca75ac833..c896165bddec02db09e9ea9399b6e627b6594c57 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -1,5 +1,11 @@ +# Note on linking: +# Client only needs to link with -lprotobuf +# Server also needs to link with -lprotoc + CPPFLAGS=-I/usr/include/xrootd -I/usr/include/protobuf3 -fPIC -std=c++1y -pedantic -Wall -Wextra -Werror -Wno-unused-parameter LDFLAGS=-L/usr/lib64/protobuf3 -lXrdSsi-4 -lXrdSsiLib +#LDLIBS=-lprotobuf -lprotoc +LDLIBS=-lprotobuf LINK.o=$(LINK.cc) all: test_client frontend_ssi.so @@ -13,13 +19,11 @@ frontend_ssi.so: TestSsiServiceProvider.o TestSsiRequestProc.o test.pb.o all: test_client -LDLIBS=-lprotobuf - test_client: test_client.o test.pb.o test_client.o: test_client.cpp TestSsiClient.h TestSsiRequest.h test.pb.h -test.pb.o: test.pb.h +test.pb.o: test.pb.cc test.pb.h test.pb.h: test.proto #protoc3 --cpp_out=. --plugin=protoc-gen-XrdSsi=./protoc-gen-XrdSsi --XrdSsi_out=. test.proto @@ -27,8 +31,6 @@ test.pb.h: test.proto # Protobuf3 plugin (to parse services in .proto file) -LDLIBS=-lprotobuf -lprotoc - protoc-gen-XrdSsi: protoc-gen-XrdSsi.cpp clean: diff --git a/frontend/TestSsiClient.h b/frontend/TestSsiClient.h index 5b649cca543574de1c7c8b861f0f4c36a441cedd..a7f0ee7c184c460b9774d756295fddd3128a2592 100644 --- a/frontend/TestSsiClient.h +++ b/frontend/TestSsiClient.h @@ -8,11 +8,6 @@ #include "XrdSsiException.h" #include "TestSsiRequest.h" -// Perhaps we want to allow multiple resources, e.g. streaming and non-streaming versions of the service? -// Can this be defined in the protobuf definition? - -const std::string TestSsiResource("/test"); - // XrdSsiProviderClient is instantiated and managed by the SSI library @@ -31,7 +26,7 @@ public: // constructor to be used on the client side (to establish a connection to the server): - TestSsiClient(std::string hostname, int port, int to = 15) : resource(TestSsiResource), timeout(to) + TestSsiClient(std::string hostname, int port, std::string _resource, int _timeout = 15) : resource(_resource), timeout(_timeout) { XrdSsiErrInfo eInfo; @@ -83,6 +78,26 @@ public: // Note: it is safe to delete the XrdSsiResource object after ProcessRequest() returns. I don't delete it because // I am assuming I can reuse it, but I need to check if that is a safe assumption. Perhaps I need to create a new // resource object for each request? + // + // See SSI ref p.10 on configuring a resource to be reusable + // Do I need more than one resource? I could have a single resource called "/default" with some default options and + // if necessary I can add other resources with other options later. + // + // Possible useful options: + // + // For specifying the tapeserver callback: + // XrdSsiResource::rInfo + // This option allows you to send additional out-of-band information to the + // server that will be executing the request. The information should be specified + // in CGI format (i.e. key=value[&key=value[...]]). This information is supplied + // to the server-side service in its corresponding request resource object. Note + // that restrictions apply for reusable resources. + // + // XrdSsiResource::rUser + // This is an arbitrary string that is meant to further identify the request. The + // SSI framework normally uses this information to tag log messages. It is also + // supplied to the server-side service in its corresponding request resource + // object. } private: diff --git a/frontend/TestSsiRequest.h b/frontend/TestSsiRequest.h index 25455251bf93aa6373b1d44284e79d7b97fc5dcc..546599ffa097cab84cb6e66db76b40c17b0b3f34 100644 --- a/frontend/TestSsiRequest.h +++ b/frontend/TestSsiRequest.h @@ -8,10 +8,10 @@ class TestSsiRequest : public XrdSsiRequest { public: - TestSsiRequest(const std::string &buffer_str, uint16_t tmo=0) : request_buffer(buffer_str.c_str()), request_len(buffer_str.size()) + TestSsiRequest(const std::string &buffer_str, uint16_t timeout=0) : request_buffer(buffer_str.c_str()), request_len(buffer_str.size()) { - std::cerr << "Creating TestSsiRequest object, setting tmo=" << tmo << std::endl; - this->SetTimeOut(tmo); + std::cerr << "Creating TestSsiRequest object, setting timeout=" << timeout << std::endl; + SetTimeOut(timeout); } virtual ~TestSsiRequest() { @@ -54,7 +54,7 @@ private: // Process the response -template<class RequestType, class ResponseType, class MetadataType, class AlertType> +template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> bool TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::ProcessResponse(const XrdSsiErrInfo &eInfo, const XrdSsiRespInfo &rInfo) { using namespace std; @@ -131,7 +131,7 @@ bool TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::Process -template<class RequestType, class ResponseType, class MetadataType, class AlertType> +template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> XrdSsiRequest::PRD_Xeq TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::ProcessResponseData(const XrdSsiErrInfo &eInfo, char *myBuff, int myBLen, bool isLast) { using namespace std; @@ -176,7 +176,7 @@ XrdSsiRequest::PRD_Xeq TestSsiRequest<RequestType, ResponseType, MetadataType, A -template<class RequestType, class ResponseType, class MetadataType, class AlertType> +template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> void TestSsiRequest<RequestType, ResponseType, MetadataType, AlertType>::Alert(XrdSsiRespInfoMsg &aMsg) { using namespace std; diff --git a/frontend/TestSsiRequestProc.cpp b/frontend/TestSsiRequestProc.cpp index d6d280b0d4fd8be6c5d7b5722c5be47a580517fc..9c18b54a591f7cd110e80186dfe1e803a5d698a0 100644 --- a/frontend/TestSsiRequestProc.cpp +++ b/frontend/TestSsiRequestProc.cpp @@ -1,8 +1,9 @@ #include <iostream> +#include "test_util.h" +#include "test.pb.h" #include "XrdSsiException.h" #include "TestSsiRequestProc.h" -#include "TestSsiProtobuf.h" // This is for specialized private methods called by RequestProc::Execute to handle actions, alerts // and metadata @@ -13,7 +14,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta // Output message in Json format (for debugging) std::cerr << "Received message:" << std::endl; - std::cerr << xrdssi::test::MessageToJsonString(request); + std::cerr << MessageToJsonString(request); // Set reply @@ -23,7 +24,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta // Output message in Json format (for debugging) std::cerr << "Preparing response:" << std::endl; - std::cerr << xrdssi::test::MessageToJsonString(response); + std::cerr << MessageToJsonString(response); } @@ -42,7 +43,7 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta // Output message in Json format (for debugging) std::cerr << "Preparing metadata..." << std::endl; - std::cerr << xrdssi::test::MessageToJsonString(metadata); + std::cerr << MessageToJsonString(metadata); } diff --git a/frontend/TestSsiServiceProvider.cpp b/frontend/TestSsiServiceProvider.cpp index 0c7306800d1136b432d99ea9a43aaba2e1661cf1..a6c30e3267af03938035adf319e060e78a0a061b 100644 --- a/frontend/TestSsiServiceProvider.cpp +++ b/frontend/TestSsiServiceProvider.cpp @@ -1,8 +1,8 @@ #include <iostream> -#include "TestSsiServiceProvider.h" +#include "test.pb.h" #include "TestSsiService.h" -#include "TestSsiProtobuf.h" +#include "TestSsiServiceProvider.h" diff --git a/frontend/test_client.cpp b/frontend/test_client.cpp index 6c7b438bed3ebf137cd9f442f8baf99c71990883..a2d2131463374bd92c09388a844aae2c22a0c170 100644 --- a/frontend/test_client.cpp +++ b/frontend/test_client.cpp @@ -1,15 +1,27 @@ -#include <unistd.h> // for sleep +#include <unistd.h> // for sleep +#include "test_util.h" // for Json output (only needed for debugging) -#include "TestSsiClient.h" -#include "TestSsiProtobuf.h" +#include "TestSsiClient.h" // XRootD SSI Service API +#include "test.pb.h" // Auto-generated message types from .proto file -int main(int argc, char *argv[]) -{ - // Host:port of XRootD server +// Bind the type of the XrdSsiClient to the types defined in the .proto file + +typedef TestSsiClient<xrdssi::test::Request, // Request message type + xrdssi::test::Result, // Response message type + xrdssi::test::Metadata, // Metadata message type + xrdssi::test::Alert> // Alert message type + TestSsiClientType; + +// Define the location of the XRootD SSI Service + +const std::string host = "localhost"; +const int port = 10400; +const std::string resource = "/test"; - const std::string host = "localhost"; - const int port = 10400; + +int main(int argc, char *argv[]) +{ // Verify that the version of the Google Protocol Buffer library that we linked against is // compatible with the version of the headers we compiled against @@ -17,9 +29,10 @@ int main(int argc, char *argv[]) try { + // Obtain a Service Provider - TestSsiClient<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert> test_ssi_service(host, port); + TestSsiClientType test_ssi_service(host, port, resource); // Create a Request object @@ -27,14 +40,27 @@ int main(int argc, char *argv[]) request.set_message_text("Archive some file"); - // Output message in Json format (for debugging only) + // Output message in Json format std::cout << "Sending message:" << std::endl; - std::cout << xrdssi::test::MessageToJsonString(request); + std::cout << MessageToJsonString(request); // Send the Request to the Service test_ssi_service.send(request); + + // Wait for the response callback. + // (When this loop finishes, test_ssi_service will go out-of-scope and the service will be shut down) + + std::cout << "Request sent, going to sleep..." << std::endl; + + int wait_secs = 20; + + while(--wait_secs) + { + std::cerr << "."; + sleep(1); + } } catch (std::exception& e) { @@ -43,18 +69,6 @@ int main(int argc, char *argv[]) return 1; } - // Wait for the response callback - - std::cout << "Request sent, going to sleep..." << std::endl; - - int wait_secs = 20; - - while(--wait_secs) - { - std::cerr << "."; - sleep(1); - } - std::cout << "All done, exiting." << std::endl; // Optional: Delete all global objects allocated by libprotobuf diff --git a/frontend/TestSsiProtobuf.h b/frontend/test_util.h similarity index 74% rename from frontend/TestSsiProtobuf.h rename to frontend/test_util.h index b850ab420fdf25c06295e909c3aa26d8195331bb..3dfb060af0c2d8b0b45dea40df04806691d31aaa 100644 --- a/frontend/TestSsiProtobuf.h +++ b/frontend/test_util.h @@ -1,12 +1,9 @@ -#ifndef __TEST_SSI_PROTOBUF_H -#define __TEST_SSI_PROTOBUF_H +#ifndef __TEST_UTIL_H +#define __TEST_UTIL_H #include <google/protobuf/util/json_util.h> -#include "test.pb.h" - -namespace xrdssi { -namespace test { +// Helper function for debugging inline std::string MessageToJsonString(const google::protobuf::Message &message) { @@ -23,7 +20,4 @@ inline std::string MessageToJsonString(const google::protobuf::Message &message) return output; } -} // test -} // xrdssi - #endif