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

[XrdSsi] Implements Alert messages

parent a591129c
No related branches found
No related tags found
No related merge requests found
......@@ -3,10 +3,9 @@
#include "test.pb.h"
#include "XrdSsiException.h"
#include "TestSsiRequestProc.h"
#include "XrdSsiPbRequestProc.h"
// This is for specialized private methods called by RequestProc::Execute to handle actions, alerts
// and metadata
// This is for specialized private methods called by RequestProc::Execute to handle actions, alerts and metadata
template <>
void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>::ExecuteAction()
......@@ -48,29 +47,22 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Meta
/*
* Alert messages can be anything you want them to be. The SSI framework enforces
* the following rules:
*
* - alerts are sent in the order posted,
* - all outstanding alerts are sent before the final response is sent (i.e. the one
* posted using a SetResponse() method),
* - once a final response is posted, subsequent alert messages are not sent, and
* - if a request is cancelled, all pending alerts are discarded.
*
* In order to send an alert, you must encapsulate your message using an
* XrdSsiRespInfoMsg object. The object provides synchronization between posting
* an alert, sending the alert, and releasing storage after the alert was sent. It is defined
* in the XrdSsiRespInfo.hh header file.
*
* The XrdSsiRespInfoMsg object needs to be inherited by whatever class you use to
* manage your alert message. The pure abstract class, RecycleMsg() must also be
* implemented. This method is called after the message is sent or when it is discarded.
* A parameter to the method tells you why it’s being called.
*
* See example p.45
// Alert messages can be anything you want them to be. The SSI framework enforces the following rules:
//
// * alerts are sent in the order posted
// * all outstanding alerts are sent before the final response is sent (i.e. the one posted using a
// SetResponse() method)
// * once a final response is posted, subsequent alert messages are not sent
// * if a request is cancelled, all pending alerts are discarded
template <>
void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>::ExecuteAlert()
void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>::ExecuteAlerts()
{
// Set alert message
m_alert.set_message_text("Something bad happened");
// Send the alert message
Alert(m_alert);
}
*/
......@@ -2,8 +2,7 @@
#define __TEST_SSI_SERVICE_H
#include <XrdSsi/XrdSsiService.hh>
#include "TestSsiRequestProc.h"
#include "XrdSsiPbRequestProc.h"
......@@ -19,8 +18,8 @@ public:
virtual ~TestSsiService() {}
// The pure abstract method ProcessRequest() is called when the client calls its ProcessRequest() method to hand off
// its request and resource objects. The clients request and resource objects are transmitted to the server and passed
// into the services ProcessRequest() method.
// its request and resource objects. The client's request and resource objects are transmitted to the server and passed
// into the service's ProcessRequest() method.
virtual void ProcessRequest(XrdSsiRequest &reqRef, XrdSsiResource &resRef) override;
......
#include <iostream>
#include "XrdSsiPbAlert.h"
#include "test.pb.h"
#include "TestSsiService.h"
#include "TestSsiServiceProvider.h"
/*
* The service provider object is pointed to by the global pointer XrdSsiProviderServer which you
* must define and set at library load time (i.e. it is a file level global static symbol).
*
* When your library is loaded, the XrdSsiProviderServer symbol is located in the library.
* Initialization fails if the appropriate symbol cannot be found or it is a NULL pointer.
*/
// The service provider object is pointed to by the global pointer XrdSsiProviderServer which you
// must define and set at library load time (i.e. it is a file level global static symbol).
//
// When your library is loaded, the XrdSsiProviderServer symbol is located in the library.
// Initialization fails if the appropriate symbol cannot be found or it is a NULL pointer.
XrdSsiProvider *XrdSsiProviderServer = new TestSsiServiceProvider;
// XrdSsiProviderClient is instantiated and managed by the SSI library
//extern XrdSsiProvider *XrdSsiProviderClient;
bool TestSsiServiceProvider::Init(XrdSsiLogger *logP, XrdSsiCluster *clsP, const std::string cfgFn, const std::string parms, int argc, char **argv)
......
#ifndef __XRD_SSI_PB_ALERT_H
#define __XRD_SSI_PB_ALERT_H
#include <XrdSsi/XrdSsiRespInfo.hh>
#include "XrdSsiException.h"
template<typename AlertType>
class AlertMsg : public XrdSsiRespInfoMsg
{
public:
AlertMsg(const AlertType &alert) : XrdSsiRespInfoMsg(nullptr, 0)
{
// Serialize the Alert
if(!alert.SerializeToString(&alert_str))
{
throw XrdSsiException("alert.SerializeToString() failed");
}
msgBuf = const_cast<char*>(alert_str.c_str());
msgLen = alert_str.size();
}
~AlertMsg() {}
void RecycleMsg(bool sent=true) { delete this; }
private:
std::string alert_str;
};
#endif
......@@ -5,8 +5,8 @@
// XRootD SSI + Protocol Buffers callbacks.
// The client should define a specialized callback type for each XRootD reply type (Response, Metadata, Alert)
// XRootD SSI + Protocol Buffers callbacks: The client should specialize on this class for each XRootD reply type
// (Response, Metadata, Alert, Error)
template<typename CallbackArg>
class XrdSsiPbRequestCallback
......@@ -47,8 +47,6 @@ public:
//
// The thread used to initiate a request may be the same one used in the GetRequest() call.
// Query for Andy: shouldn't the return type for GetRequest be const?
virtual char *GetRequest(int &reqlen) override { reqlen = m_request_len; return const_cast<char*>(m_request_bufptr); }
// Requests are sent to the server asynchronously via the service object. The ProcessResponse() callback
......@@ -56,7 +54,7 @@ public:
virtual bool ProcessResponse(const XrdSsiErrInfo &eInfo, const XrdSsiRespInfo &rInfo) override;
// ProcessReesponseData() is an optional callback used in conjunction with the request's GetResponseData() method,
// ProcessResponseData() is an optional callback used in conjunction with the request's GetResponseData() method,
// or when the response is a data stream and you wish to asynchronously receive data via the stream. Most
// applications will need to implement this as scalable applications generally require that any large amount of
// data be asynchronously received.
......@@ -95,9 +93,7 @@ private:
template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType>
bool XrdSsiPbRequest<RequestType, ResponseType, MetadataType, AlertType>::ProcessResponse(const XrdSsiErrInfo &eInfo, const XrdSsiRespInfo &rInfo)
{
using namespace std;
cerr << "ProcessResponse() callback called with response type = " << rInfo.State() << endl;
std::cerr << "ProcessResponse() callback called with response type = " << rInfo.State() << std::endl;
switch(rInfo.rType)
{
......@@ -196,10 +192,6 @@ template<typename RequestType, typename ResponseType, typename MetadataType, typ
XrdSsiRequest::PRD_Xeq XrdSsiPbRequest<RequestType, ResponseType, MetadataType, AlertType>
::ProcessResponseData(const XrdSsiErrInfo &eInfo, char *response_bufptr, int response_buflen, bool is_last)
{
using namespace std;
// If we can't handle the queue at this time, return XrdSsiRequest::PRD_Hold;
// The buffer length can be 0 if the response is metadata only
if(response_buflen != 0)
......@@ -243,25 +235,37 @@ XrdSsiRequest::PRD_Xeq XrdSsiPbRequest<RequestType, ResponseType, MetadataType,
}
return XrdSsiRequest::PRD_Normal; // Indicate what type of post-processing is required (normal in this case)
// If we can't handle the queue at this time, return XrdSsiRequest::PRD_Hold;
}
template<typename RequestType, typename ResponseType, typename MetadataType, typename AlertType>
void XrdSsiPbRequest<RequestType, ResponseType, MetadataType, AlertType>::Alert(XrdSsiRespInfoMsg &aMsg)
void XrdSsiPbRequest<RequestType, ResponseType, MetadataType, AlertType>::Alert(XrdSsiRespInfoMsg &alert_msg)
{
using namespace std;
// Get the Alert
int alert_len;
char *alert_buffer = alert_msg.GetMsg(alert_len);
// Deserialize the Alert
int aMsgLen;
char *aMsgData = aMsg.GetMsg(aMsgLen);
const std::string alert_str(alert_buffer, alert_len);
// Process the alert
AlertType alert;
cout << "Received Alert message: " << aMsgData << endl;
if(alert.ParseFromString(alert_str))
{
AlertCallback(alert);
}
else
{
ErrorCallback("alert.ParseFromString() failed");
}
// Failure to recycle the message will cause a memory leak
// Recycle the message to free memory
aMsg.RecycleMsg();
alert_msg.RecycleMsg();
}
#endif
#ifndef __TEST_SSI_REQUEST_PROC_H
#define __TEST_SSI_REQUEST_PROC_H
#ifndef __XRD_SSI_PB_REQUEST_PROC_H
#define __XRD_SSI_PB_REQUEST_PROC_H
#include <XrdSsi/XrdSsiResponder.hh>
#include "XrdSsiException.h"
#include "XrdSsiPbAlert.h"
/*
* The XrdSsiResponder class knows how to safely interact with the request object. It allows handling asynchronous
......@@ -29,6 +30,16 @@ public:
virtual void Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel=false) override;
private:
void Alert(const AlertType &alert)
{
// Encapsulate the Alert protocol buffer inside a XrdSsiRespInfoMsg object. Alert message objects
// are created on the heap with lifetime managed by the XrdSsiResponder class.
XrdSsiResponder::Alert(*(new AlertMsg<AlertType>(alert)));
}
// These methods should be specialized according to the needs of each <RequestType, ResponseType> pair
void ExecuteAction() { std::cerr << "Called default ExecuteAction()" << std::endl; }
......@@ -37,8 +48,8 @@ private:
RequestType m_request;
ResponseType m_response;
MetadataType m_metadata;
AlertType m_alert;
MetadataType m_metadata;
};
......
......@@ -20,6 +20,17 @@ void XrdSsiPbRequestCallback<std::string>::operator()(const std::string &error_t
// Alert callback
template<>
void XrdSsiPbRequestCallback<xrdssi::test::Alert>::operator()(const xrdssi::test::Alert &alert)
{
std::cout << "AlertCallback():" << std::endl;
std::cout << MessageToJsonString(alert);
}
// Metadata callback
template<>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment