#ifndef __XRDSSISERVICE_HH__
#define __XRDSSISERVICE_HH__
/******************************************************************************/
/* */
/* X r d S s i S e r v i c e . h h */
/* */
/* (c) 2015 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
#include
//-----------------------------------------------------------------------------
//! The XrdSsiService object is used by the Scalable Service Interface to
//! process client requests.
//!
//! There may be many client-side service objects, as needed. However, only
//! one such object is obtained server-side. The object is used to effect all
//! service requests and handle responses.
//!
//! Client-side: the service object is obtained via the object pointed to by
//! XrdSsiProviderClient defined in libXrdSsi.so
//!
//! Server-side: the service object is obtained via the object pointed to by
//! XrdSsiProviderServer defined in the plugin shared library.
//-----------------------------------------------------------------------------
class XrdSsiErrInfo;
class XrdSsiRequest;
class XrdSsiResource;
class XrdSsiService
{
public:
//-----------------------------------------------------------------------------
//! Obtain the version of the abstract class used by underlying implementation.
//! The version returned must match the version compiled in the loading library.
//! If it does not, initialization fails.
//-----------------------------------------------------------------------------
static const int SsiVersion = 0x00020000;
int GetVersion() {return SsiVersion;}
//-----------------------------------------------------------------------------
//! @brief Attach to a backgrounded request.
//!
//! When a client calls Attach() the server-side Attach() is invoked to
//! indicate that the backgrounded request is now a foreground request. Many
//! times such notification is not needed so a default nil implementation is
//! provided. Server-side Attach() calls are always passed the original request
//! object reference so that it can pair up the request with the attach.
//!
//! @param eInfo Reference to an error info object which will contain the
//! error describing why the attach failed (i.e. return false).
//!
//! @param handle Reference to the handle provided to the callback method
//! XrdSsiRequest::ProcessResponse() via isHandle response type.
//! This is always an empty string on server-side calls.
//!
//! @param reqRef Reference to the request object that is to attach to the
//! backgrounded request. It need not be the original request
//! object (client-side) but it always is the original request
//! object server-side.
//!
//! @param resP A pointer to the resource object describing the request
//! resources. This is meaningless for client calls and should
//! not be specified. For server-side calls, it can be used to
//! reauthorize the request since the client performing the
//! attach may be different from the client that actually
//! started the request.
//!
//! @return true Continue normally, no issues detected.
//! false An exception occurred, the eInfo object has the reason. For
//! server side calls this provides the service the ability to
//! reject request reattachment.
//-----------------------------------------------------------------------------
virtual bool Attach( XrdSsiErrInfo &eInfo,
const std::string &handle,
XrdSsiRequest &reqRef,
XrdSsiResource *resP=0
) {return true;}
//-----------------------------------------------------------------------------
//! @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.
//!
//! When a client calls ProcessRequest() the same method is called server-side
//! with the same parameters that the client specified except for timeOut which
//! is always set to zero server-side.
//!
//! @param reqRef Reference to the Request object that describes the
//! request.
//!
//! @param resRef Reference to the Resource object that describes the
//! resource that the request will be using.
//!
//! All results are returned via the request object callback methods.
//! For background queries, the XrdSsiRequest::ProcessResponse() is
//! called with a response type of isHandle when the request is handed
//! off to the endpoint for execution (see XrdSsiRequest::SetDetachTTL).
//-----------------------------------------------------------------------------
virtual void ProcessRequest(XrdSsiRequest &reqRef,
XrdSsiResource &resRef
) = 0;
//-----------------------------------------------------------------------------
//! @brief Stop the client-side service. This is never called server-side.
//!
//! @param immed When true, the service is only stopped if here are no
//! active requests. Otherwise, after all requests have
//! finished. the service object is deleted.
//!
//! @return true Service has been stopped. Once all requests have been
//! completed, the service object will be deleted.
//! @return false Service cannot be stopped because there are still active
//! foreground requests and the immed parameter was true.
//-----------------------------------------------------------------------------
virtual bool Stop(bool immed=false) {return !immed;}
//-----------------------------------------------------------------------------
//! Constructor
//-----------------------------------------------------------------------------
XrdSsiService() {}
protected:
//-----------------------------------------------------------------------------
//! Destructor. The service object cannot be explicitly deleted. Use Stop().
//-----------------------------------------------------------------------------
virtual ~XrdSsiService() {}
};
#endif