2015-03-18 14:48:43 -04:00
# include "GxsResponseTask.h"
# include "Operators.h"
namespace resource_api
{
GxsResponseTask : : GxsResponseTask ( RsIdentity * id_service , RsTokenService * token_service ) :
mIdService ( id_service ) , mTokenService ( token_service ) ,
mDone ( false )
{
}
bool GxsResponseTask : : doWork ( Request & req , Response & resp )
{
bool ready = true ;
// check if gxs requests are ready
if ( mTokenService & & ! mWaitingTokens . empty ( ) )
{
for ( std : : vector < uint32_t > : : iterator vit = mWaitingTokens . begin ( ) ; vit ! = mWaitingTokens . end ( ) ; + + vit )
{
uint8_t status = mTokenService - > requestStatus ( * vit ) ;
if ( status ! = RsTokenService : : GXS_REQUEST_V2_STATUS_COMPLETE )
{
ready = false ;
}
if ( status = = RsTokenService : : GXS_REQUEST_V2_STATUS_FAILED )
{
std : : cerr < < " GxsResponseTask::doWork() Error: token failed. aborting. " < < std : : endl ;
resp . setFail ( " GxsResponseTask::doWork() Error: token failed. " ) ;
return false ; // don't continue
}
}
}
if ( mIdService = = 0 )
{
std : : cerr < < " GxsResponseTask::doWork() ERROR: constucted with idservice = 0. Fix your code or report this bug. " < < std : : endl ;
resp . setFail ( " GxsResponseTask::doWork() ERROR: constucted with idservice = 0. Fix your code or report this bug. " ) ;
return false ; // don't continue
}
// check if we have identities to fetch
bool more = true ;
while ( ! mIdentitiesToFetch . empty ( ) & & more )
{
// there are two methods to fetch identity data:
// - request gxs group, get token, get group
// - the direct way where we may have to wait, but identities will cache the result
// if we need to get many identuties, then we may flush the cache
// but if we reaquest the groups, no caching is done on the rs side (OS will cache the identities file)
// it has to be measured what is better
RsGxsId id = mIdentitiesToFetch . back ( ) ;
RsIdentityDetails details ;
if ( mIdService - > getIdDetails ( id , details ) )
{
mIdentitiesToFetch . pop_back ( ) ;
mIdentityDetails . push_back ( details ) ;
}
else
{
more = false ; // pause when an id failed, to give the service time tim fetch the data
ready = false ;
2016-02-14 08:57:41 -05:00
// TODO: remove identities which failed many times from list, to avoid blocking when ids fail
2015-03-18 14:48:43 -04:00
}
}
if ( ! ready )
return true ; // want to continue later
mWaitingTokens . clear ( ) ;
mIdentitiesToFetch . clear ( ) ;
gxsDoWork ( req , resp ) ;
if ( mDone ) return false ;
else return true ;
}
void GxsResponseTask : : addWaitingToken ( uint32_t token )
{
if ( mTokenService )
mWaitingTokens . push_back ( token ) ;
else
std : : cerr < < " GxsResponseTask::addWaitingToken() ERROR: constructed with tokenservice=0. Unable to handle token processing. Fix your code or report this bug. " < < std : : endl ;
}
void GxsResponseTask : : done ( )
{
mDone = true ;
}
void GxsResponseTask : : requestGxsId ( RsGxsId id )
{
mIdentitiesToFetch . push_back ( id ) ;
}
void GxsResponseTask : : streamGxsId ( RsGxsId id , StreamBase & stream )
{
// will see if this works or if we have to use an index
for ( std : : vector < RsIdentityDetails > : : iterator vit = mIdentityDetails . begin ( ) ;
vit ! = mIdentityDetails . end ( ) ; + + vit )
{
if ( vit - > mId = = id )
{
stream < < makeKeyValueReference ( " id " , id )
< < makeKeyValueReference ( " gxs_id " , id )
2015-11-19 21:14:32 -05:00
< < makeKeyValueReference ( " flags " , vit - > mFlags )
< < makeKeyValueReference ( " name " , vit - > mNickname ) ;
2015-03-18 14:48:43 -04:00
return ;
}
}
}
2015-07-29 09:02:10 -04:00
std : : string GxsResponseTask : : getName ( RsGxsId id )
{
for ( std : : vector < RsIdentityDetails > : : iterator vit = mIdentityDetails . begin ( ) ;
vit ! = mIdentityDetails . end ( ) ; + + vit )
{
if ( vit - > mId = = id )
return vit - > mNickname ;
}
std : : cerr < < " Warning: identity not found in GxsResponseTask::getName(). This is probably a bug. You must call GxsResponseTask::requestGxsId() before you can get the name. " < < std : : endl ;
return " " ;
}
2015-03-18 14:48:43 -04:00
} // namespace resource_api