updated RsGenExchange::performUpdateValidation to simplify the logic and save (oldGrp,newGrp) in a specific RsGxsGroupUpdate subclass of GxsNotify so as to be able to handle group data notifications in services

This commit is contained in:
csoler 2020-04-26 00:18:01 +02:00
parent b2e36fbd9c
commit ae54e53bc1
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
3 changed files with 61 additions and 45 deletions

View File

@ -149,7 +149,7 @@ public:
bool withMeta = false ) = 0;
/*!
* Retrieves all groups stored
* Retrieves all groups stored. Caller owns the memory and is supposed to delete the RsNxsGrp pointers after use.
* @param grp retrieved groups
* @param withMeta if true the meta handle of nxs grps is intitialised
* @param cache whether to store retrieval in mem for faster later retrieval

View File

@ -3230,39 +3230,41 @@ void RsGenExchange::performUpdateValidation()
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
RsGxsGrpMetaTemporaryMap grpMetas;
RsNxsGrpDataTemporaryMap grpDatas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
grpDatas.insert(std::make_pair(vit->newGrp->grpId, (RsNxsGrp*)NULL));
if(grpDatas.empty() || !mDataStore->retrieveNxsGrps(grpDatas,true,false))
{
if(grpDatas.empty())
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: no group in list!" << std::endl;
else
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: cannot retrieve froup data for these groups!" << std::endl;
if(!grpMetas.empty())
mDataStore->retrieveGxsGrpMetaData(grpMetas);
else
return;
vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
}
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
vit = mGroupUpdates.begin();
RsNxsGrpDataTemporaryList grps ;
for(; vit != mGroupUpdates.end(); ++vit)
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
if(gu.validUpdate)
auto mit = grpDatas.find(gu.newGrp->grpId);
if(mit == grpDatas.end())
{
RsErr() << __PRETTY_FUNCTION__ << " Validation of group update failed for group " << gu.newGrp->grpId << " because previous grp version cannot be found." << std::endl;
continue;
}
RsGxsGrpMetaData *oldGrpMeta(mit->second->metaData);
if(updateValid(*oldGrpMeta, *gu.newGrp))
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
@ -3270,14 +3272,28 @@ void RsGenExchange::performUpdateValidation()
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
gu.newGrp->metaData->mSubscribeFlags = oldGrpMeta->mSubscribeFlags ;
// Also keep private keys if present
if(!gu.newGrp->metaData->keys.private_keys.empty())
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
else
gu.newGrp->metaData->keys.private_keys = gu.oldGrpMeta->keys.private_keys ;
gu.newGrp->metaData->keys.private_keys = oldGrpMeta->keys.private_keys ;
// Now prepare notification of the client
RsGxsGroupUpdate *c = new RsGxsGroupUpdate();
c->mGroupId = gu.newGrp->grpId ;
c->mNewGroup = gu.newGrp->clone(); // make a copy because mDataStore will destroy it on update
c->mOldGroup = mit->second; // do not make a copy since we own the memory
mit->second = nullptr; // prevents deletion in auto delete map
mNotifications.push_back(c);
// finally, add the group to
grps.push_back(gu.newGrp);
}
@ -3286,26 +3302,9 @@ void RsGenExchange::performUpdateValidation()
delete gu.newGrp;
gu.newGrp = NULL ;
}
gu.oldGrpMeta = NULL ;
}
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
#ifdef GEN_EXCH_DEBUG
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
#endif
}
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
mDataStore->updateGroup(grps);
#ifdef GEN_EXCH_DEBUG

View File

@ -32,6 +32,8 @@ typedef uint32_t TurtleRequestId;
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
class RsNxsGrp;
/*!
* The aim of this class is to abstract how changes are represented so they can
* be determined outside the client API without explcitly enumerating all
@ -47,7 +49,8 @@ struct RsGxsNotify
TYPE_PROCESSED = 0x03,
TYPE_RECEIVED_PUBLISHKEY = 0x04,
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
TYPE_STATISTICS_CHANGED = 0x06
TYPE_STATISTICS_CHANGED = 0x06,
TYPE_UPDATED = 0x07,
};
virtual ~RsGxsNotify() {}
@ -60,15 +63,29 @@ struct RsGxsNotify
class RsGxsGroupChange : public RsGxsNotify
{
public:
RsGxsGroupChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
RsGxsGroupChange(NotifyType type, bool metaChange) : mNotifyType(type), mMetaChange(metaChange) {}
std::list<RsGxsGroupId> mGrpIdList;
NotifyType getType(){ return NOTIFY_TYPE;}
NotifyType getType() override { return mNotifyType;}
bool metaChange() { return mMetaChange; }
private:
const NotifyType NOTIFY_TYPE;
protected:
NotifyType mNotifyType;
bool mMetaChange;
};
class RsGxsGroupUpdate : public RsGxsNotify
{
public:
RsGxsGroupUpdate() : mOldGroup(nullptr),mNewGroup(nullptr) {}
RsGxsGroupId mGroupId;
RsNxsGrp *mOldGroup;
RsNxsGrp *mNewGroup;
NotifyType getType() override { return RsGxsNotify::TYPE_UPDATED;}
};
class RsGxsDistantSearchResultChange: public RsGxsNotify
{
public: