diff --git a/src/XrdSsi.cmake b/src/XrdSsi.cmake index 37bc3c97952..8fb6647f3bf 100644 --- a/src/XrdSsi.cmake +++ b/src/XrdSsi.cmake @@ -34,7 +34,7 @@ XrdSsi/XrdSsiRequest.cc XrdSsi/XrdSsiRequest.hh XrdSsi/XrdSsiResource.hh XrdSsi/XrdSsiScale.hh XrdSsi/XrdSsiServReal.cc XrdSsi/XrdSsiServReal.hh - XrdSsi/XrdSsiService.hh +XrdSsi/XrdSsiService.cc XrdSsi/XrdSsiService.hh XrdSsi/XrdSsiSessReal.cc XrdSsi/XrdSsiSessReal.hh XrdSsi/XrdSsiStream.hh XrdSsi/XrdSsiTaskReal.cc XrdSsi/XrdSsiTaskReal.hh diff --git a/src/XrdSsi/XrdSsiAlert.cc b/src/XrdSsi/XrdSsiAlert.cc index d8a71870e6e..fff9e3b7e0b 100644 --- a/src/XrdSsi/XrdSsiAlert.cc +++ b/src/XrdSsi/XrdSsiAlert.cc @@ -98,7 +98,7 @@ void XrdSsiAlert::Recycle() // Issue callback to release the message if we have one // - if (theMsg) theMsg->Recycle(); + if (theMsg) theMsg->RecycleMsg(); // Place object on the queue unless we have too many // diff --git a/src/XrdSsi/XrdSsiFileReq.cc b/src/XrdSsi/XrdSsiFileReq.cc index a0f05800c1b..13ab1a93a0c 100644 --- a/src/XrdSsi/XrdSsiFileReq.cc +++ b/src/XrdSsi/XrdSsiFileReq.cc @@ -139,7 +139,7 @@ void XrdSsiFileReq::Alert(XrdSsiRespInfoMsg &aMsg) // if (msgLen <= 0 || rP->rType != XrdSsiRespInfo::isNone || isEnding) {frqMutex.UnLock(); - aMsg.Recycle(); + aMsg.RecycleMsg(); return; } diff --git a/src/XrdSsi/XrdSsiFileSess.cc b/src/XrdSsi/XrdSsiFileSess.cc index fc3e138190d..b712236723c 100644 --- a/src/XrdSsi/XrdSsiFileSess.cc +++ b/src/XrdSsi/XrdSsiFileSess.cc @@ -52,6 +52,7 @@ #include "XrdSsi/XrdSsiEntity.hh" #include "XrdSsi/XrdSsiFileSess.hh" #include "XrdSsi/XrdSsiProvider.hh" +#include "XrdSsi/XrdSsiService.hh" #include "XrdSsi/XrdSsiSfs.hh" #include "XrdSsi/XrdSsiStream.hh" #include "XrdSsi/XrdSsiTrace.hh" @@ -67,6 +68,7 @@ namespace XrdSsi { extern XrdOucBuffPool *BuffPool; extern XrdSsiProvider *Provider; +extern XrdSsiService *Service; extern XrdSysError Log; extern int respWT; }; @@ -393,7 +395,7 @@ int XrdSsiFileSess::open(const char *path, // In // Notify the provider that we will be executing a request // - if (Provider->Prepare(errInfo, fileResource)) + if (Service->Prepare(errInfo, fileResource)) {const char *usr = fileResource.rUser.c_str(); if (!(*usr)) gigID = strdup(path); else {char gBuff[2048]; diff --git a/src/XrdSsi/XrdSsiProvider.hh b/src/XrdSsi/XrdSsiProvider.hh index 644a98efb17..4be00af555d 100644 --- a/src/XrdSsi/XrdSsiProvider.hh +++ b/src/XrdSsi/XrdSsiProvider.hh @@ -152,40 +152,6 @@ virtual bool Init(XrdSsiLogger *logP, char **argv ) = 0; -//----------------------------------------------------------------------------- -//! @brief Prepare for processing subsequent resource request. -//! -//! This method is meant to be used server-side to optimize subsequent request -//! processing, perform authorization, and allow a provider to stall or redirect -//! requests. It is optional and a default implementation is provided. -//! -//! @param eInfo The object where error information is to be placed. -//! @param rDesc Reference to the resource object that describes the -//! resource subsequent requests will use. -//! -//! @return true Continue normally, no issues detected. -//! false An exception occurred, the eInfo object has the reason. -//! -//! Special notes for server-side processing: -//! -//! 1) Two special errors are recognized that allow for a client retry: -//! -//! resP->eInfo.eNum = EAGAIN (client should retry elsewhere) -//! resP->eInfo.eMsg = the host name where the client is redirected -//! resP->eInfo.eArg = the port number to be used by the client -//! -//! resP->eInfo.eNum = EBUSY (client should wait and then retry). -//! resP->eInfo.eMsg = an optional reason for the wait. -//! resP->eInfo.eArg = the number of seconds the client should wait. -//----------------------------------------------------------------------------- - -virtual bool Prepare(XrdSsiErrInfo &eInfo, const XrdSsiResource &rDesc) - {if (QueryResource(rDesc.rName.c_str()) != notPresent) - return true; - eInfo.Set("Resource not available.", ENOENT); - return false; - } - //----------------------------------------------------------------------------- //! Obtain the status of a resource. //! Client-side: This method can be called to obtain the availability of a diff --git a/src/XrdSsi/XrdSsiRequest.hh b/src/XrdSsi/XrdSsiRequest.hh index b1214069873..98de6e96ee3 100644 --- a/src/XrdSsi/XrdSsiRequest.hh +++ b/src/XrdSsi/XrdSsiRequest.hh @@ -86,7 +86,7 @@ friend class XrdSsiTaskReal; //! you have consumed the message to release its resources. //----------------------------------------------------------------------------- -virtual void Alert(XrdSsiRespInfoMsg &aMsg) {aMsg.Recycle(false);} +virtual void Alert(XrdSsiRespInfoMsg &aMsg) {aMsg.RecycleMsg(false);} //----------------------------------------------------------------------------- //! Indicate that request processing has been finished. This method calls diff --git a/src/XrdSsi/XrdSsiRespInfo.hh b/src/XrdSsi/XrdSsiRespInfo.hh index 13845930c47..841fdf92480 100644 --- a/src/XrdSsi/XrdSsiRespInfo.hh +++ b/src/XrdSsi/XrdSsiRespInfo.hh @@ -76,8 +76,8 @@ struct XrdSsiRespInfo //----------------------------------------------------------------------------- //! The RespInfoMsg class describes an async response message sent to the -//! XrdSsiRequest::Alert() method. It encapsulates the message sent and is -//! responsible for recovering any resources used by the message via Recycle(). +//! XrdSsiRequest::Alert() method. It encapsulates the message sent and must +//! recover any resources used by the message when RecycleMsg() is called. //----------------------------------------------------------------------------- class XrdSsiRespInfoMsg @@ -99,10 +99,10 @@ inline char *GetMsg(int &mlen) {mlen = msgLen; return msgBuf;} //! Release resources used by the message. This method must be called after the //! message is processed by the XrdSsiRequest::Alert() method. //! -//! Qparam sent When true, the message was sent. Otherwise, it was not sent. +//! @param sent When true, the message was sent. Otherwise, it was not sent. //----------------------------------------------------------------------------- -virtual void Recycle(bool sent=true) = 0; +virtual void RecycleMsg(bool sent=true) = 0; //----------------------------------------------------------------------------- //! Contructor diff --git a/src/XrdSsi/XrdSsiResponder.hh b/src/XrdSsi/XrdSsiResponder.hh index c49e8a60928..0b119829c01 100644 --- a/src/XrdSsi/XrdSsiResponder.hh +++ b/src/XrdSsi/XrdSsiResponder.hh @@ -108,7 +108,7 @@ protected: //! Send an alert message to the request. This is a convenience method that //! avoids race condistions with Finished() so it is safe to use in all cases. //! This is a server-side call. The service is responsible for creating a -//! RespInfoMsg object containing the message and supplying a Recycle() method. +//! RespInfoMsg object containing the message and supplying a RecycleMsg() method. //! //! @param aMsg reference to the message to be sent. //----------------------------------------------------------------------------- @@ -116,7 +116,7 @@ protected: inline void Alert(XrdSsiRespInfoMsg &aMsg) {XrdSsiMutexMon(rrMutex); if (reqP) reqP->Alert(aMsg); - else aMsg.Recycle(false); + else aMsg.RecycleMsg(false); } //----------------------------------------------------------------------------- diff --git a/src/XrdSsi/XrdSsiService.cc b/src/XrdSsi/XrdSsiService.cc new file mode 100644 index 00000000000..fb06aa120c0 --- /dev/null +++ b/src/XrdSsi/XrdSsiService.cc @@ -0,0 +1,58 @@ +/******************************************************************************/ +/* */ +/* X r d S s i S e r v i c e . c c */ +/* */ +/* (c) 2017 by the Board of Trustees of the Leland Stanford, Jr., University */ +/* Produced by Andrew Hanushevsky for Stanford University under contract */ +/* DE-AC02-76-SFO0515 with the Department of Energy */ +/* */ +/* This file is part of the XRootD software suite. */ +/* */ +/* XRootD is free software: you can redistribute it and/or modify it under */ +/* the terms of the GNU Lesser General Public License as published by the */ +/* Free Software Foundation, either version 3 of the License, or (at your */ +/* option) any later version. */ +/* */ +/* XRootD is distributed in the hope that it will be useful, but WITHOUT */ +/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ +/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ +/* License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ +/* COPYING (GPL license). If not, see . */ +/* */ +/* The copyright holder's institutional names and contributor's names may not */ +/* be used to endorse or promote products derived from this software without */ +/* specific prior written permission of the institution or contributor. */ +/******************************************************************************/ + +#include "XrdSsiProvider.hh" +#include "XrdSsiService.hh" + +/******************************************************************************/ +/* G l o b a l I t e m s */ +/******************************************************************************/ + +namespace XrdSsi +{ +extern XrdSsiProvider *Provider; +} + +/******************************************************************************/ +/* P r e p a r e */ +/******************************************************************************/ + +bool XrdSsiService::Prepare(XrdSsiErrInfo &eInfo, const XrdSsiResource &rDesc) +{ +// The default implementation simply asks the proviuder if the resource exists +// + if (XrdSsi::Provider + && XrdSsi::Provider->QueryResource(rDesc.rName.c_str()) != + XrdSsiProvider::notPresent) return true; + +// Indicate we do not have the resource +// + eInfo.Set("Resource not available.", ENOENT); + return false; +} diff --git a/src/XrdSsi/XrdSsiService.hh b/src/XrdSsi/XrdSsiService.hh index 36fff9cac81..02ea8db84b2 100644 --- a/src/XrdSsi/XrdSsiService.hh +++ b/src/XrdSsi/XrdSsiService.hh @@ -47,6 +47,7 @@ //! XrdSsiProviderServer defined in the plugin shared library. //----------------------------------------------------------------------------- +class XrdSsiErrInfo; class XrdSsiRequest; class XrdSsiResource; @@ -86,6 +87,37 @@ static const int SsiVersion = 0x00020000; virtual void Attach(XrdSsiRequest &reqRef, std::string handle) {} +//----------------------------------------------------------------------------- +//! @brief Prepare for processing subsequent resource request. +//! +//! This method is meant to be used server-side to optimize subsequent request +//! processing, perform authorization, and allow a service to stall or redirect +//! requests. It is optional and a default implementation is provided that +//! simply asks the provider if the resource exists on the server. Clients need +//! not call or implement this method. +//! +//! @param eInfo The object where error information is to be placed. +//! @param rDesc Reference to the resource object that describes the +//! resource subsequent requests will use. +//! +//! @return true Continue normally, no issues detected. +//! false An exception occurred, the eInfo object has the reason. +//! +//! Special notes for server-side processing: +//! +//! 1) Two special errors are recognized that allow for a client retry: +//! +//! resP->eInfo.eNum = EAGAIN (client should retry elsewhere) +//! resP->eInfo.eMsg = the host name where the client is redirected +//! resP->eInfo.eArg = the port number to be used by the client +//! +//! resP->eInfo.eNum = EBUSY (client should wait and then retry). +//! resP->eInfo.eMsg = an optional reason for the wait. +//! resP->eInfo.eArg = the number of seconds the client should wait. +//----------------------------------------------------------------------------- + +virtual bool Prepare(XrdSsiErrInfo &eInfo, const XrdSsiResource &rDesc); + //----------------------------------------------------------------------------- //! @brief Process a request; client-side or server-side. //! diff --git a/src/XrdSsi/XrdSsiTaskReal.cc b/src/XrdSsi/XrdSsiTaskReal.cc index 2b1019991ba..cd5972819cf 100644 --- a/src/XrdSsi/XrdSsiTaskReal.cc +++ b/src/XrdSsi/XrdSsiTaskReal.cc @@ -78,7 +78,7 @@ class AlertMsg : public XrdSsiRespInfoMsg { public: -void Recycle(bool sent=true) {delete respObj; delete this;} +void RecycleMsg(bool sent=true) {delete respObj; delete this;} AlertMsg(XrdCl::AnyObject *resp, char *dbuff, int dlen) : XrdSsiRespInfoMsg(dbuff, dlen), respObj(resp) {}