Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/NotificationManagement/handler_notification.cpp
T
berrux-dev c3eda18234 Migrates remaining services and plugins to generated rtiddsgen API
Converts accessor calls to plain member access across the residual service set.
2026-09-21 02:47:48 +02:00

261 lines
8.2 KiB
C++
Executable File

/**
* Handler for all notification objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, ESZS, 2025-06-23
*/
#include "handler_notification.h"
#include "object_notification.h"
#include "dds_handler.h"
#include "settings.h"
#include <ngldb/dbtransaction.h>
namespace NotificationManagement
{
HandlerNotification::HandlerNotification(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DatabaseInterface> &db)
: Interface::Fts::CreateNotificationRequestHandler(ddsHandler->fts())
, Interface::Fts::ReadReceiptRequestHandler(ddsHandler->fts())
, Interface::Fts::DeleteMessageRequestHandler(ddsHandler->fts())
, m_removeNotificationTimer(new QTimer())
, m_ddsHandler(ddsHandler)
, m_db(db)
, m_logger(getLogger("HandlerNotification"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerNotification::~HandlerNotification()
{
qDeleteAll(m_objectNotificationMap);
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerNotification::init()
{
INFO_LOG(m_logger) << "--- Start NotificationManagement HandlerNotification.";
QVector<Database::NomAddress> dataAddressVec;
// read all addresses from database
if (!m_db->select(dataAddressVec))
{
ERROR_LOG(m_logger) << "Error reading address data from database!";
return false;
}
// create NotificationObjects
bool bRet = true;
QList<int> removeNotificationIds;
auto cb = [this, &bRet, &dataAddressVec, &removeNotificationIds] (const Database::NomNotification &dbNotif)
{
static NomNotification notif = ObjectNotification::toDdsData(dbNotif);
// Remove old notifications
if (isRemoveable(notif))
{
INFO_LOG(m_logger) << "Remove old notification " << notif.title << ", id = " << notif.id;
removeNotificationIds.append(notif.id);
return;
}
// alle Addressen zu der NomNotification eintragen
for (const Database::NomAddress &addr : qAsConst(dataAddressVec))
{
if (addr.notificationId == notif.id)
{
if (addr.isSender)
notif.sender = ObjectNotification::toDdsData(addr);
else
notif.recipientIds.push_back(ObjectNotification::toDdsData(addr));
}
}
ObjectNotification *ifs(new ObjectNotification(m_ddsHandler, m_db));
Core::FunctionReplyObject ret = ifs->createObject(notif);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_objectNotificationMap.insert(ifs->id(), ifs);
};
if (!m_db->select(cb) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
// Remove old notifications here - not possible in select
DBTransaction trans(m_db->database());
for (int notificationId : removeNotificationIds)
m_db->removeNomNotification(notificationId);
trans.commit();
DEBUG_LOG(m_logger) << "m_objectNotificationMap.size() = " << m_objectNotificationMap.size();
if (!m_ddsHandler->fts())
{
ERROR_LOG(m_logger) << "m_ddsHandler->fts() == nullptr!";
return false;
}
// ExerciseChanged for removing notifications
connect(m_ddsHandler->dtcExm().get(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
this, &HandlerNotification::onExerciseChanged);
// Setup removeNotificaitonTimer
m_removeNotificationTimer->setTimerType(Qt::TimerType::VeryCoarseTimer);
// Check every 10 seconds (default)
m_removeNotificationTimer->setInterval(Settings::removeTimerIntervalMSec());
connect(m_removeNotificationTimer, &QTimer::timeout, this, &HandlerNotification::onCheckRemove);
m_removeNotificationTimer->start();
DEBUG_LOG(m_logger) << "removeTimerInterval: " << Settings::removeTimerIntervalMSec();
DEBUG_LOG(m_logger) << "expiryTime: " << Settings::expiryIntervalMSec();
return true;
} // end of init()
//-----------------------------------------------------------------------------
void HandlerNotification::onCreateNotificationRequest(const rti::core::SampleIdentity &cookie,
const CreateNotification &request)
{
DEBUG_LOG(m_logger) << "onCreateNotificationRequest: " << request;
ObjectNotification *ifs(new ObjectNotification(m_ddsHandler, m_db));
const Core::FunctionReplyObject ret = ifs->createObject(request.notification);
if (ret.error())
{
delete ifs;
WARNING_LOG(m_logger) << ret();
m_ddsHandler->fts()->createNotificationReply(cookie, ret);
return;
}
m_objectNotificationMap.insert(ifs->id(), ifs);
m_ddsHandler->fts()->createNotificationReply(cookie, ret);
}
// end of onCreateNotificationRequest
//-----------------------------------------------------------------------------
void HandlerNotification::onReadReceiptRequest(const rti::core::SampleIdentity &cookie,
const ReadReceipt &request)
{
DEBUG_LOG(m_logger) << "onReadReceiptRequest: " << request;
Core::FunctionReplyObject ret;
for (const auto notificationId : request.notificationIds)
{
ObjectNotification *ifs = m_objectNotificationMap.value(notificationId);
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(notificationId,
tr_lts("dds", "NomNotification with id %1 not found")).arg(notificationId);
m_ddsHandler->fts()->readReceiptReply(cookie, ret);
return;
}
ret = ifs->readReceipt(request, notificationId);
}
m_ddsHandler->fts()->readReceiptReply(cookie, ret);
}
void HandlerNotification::onDeleteMessageRequest(const rti::core::SampleIdentity &cookie, const DeleteMessage &request)
{
DEBUG_LOG(m_logger) << "onDeleteMessageRequest: " << request;
Core::FunctionReplyObject ret;
for (const auto notificationId : request.notificationIds)
{
ObjectNotification *ifs = m_objectNotificationMap.value(notificationId);
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(notificationId, tr_lts("dds", "NomNotification with id %1 not found")).arg(notificationId);
m_ddsHandler->fts()->deleteMessageReply(cookie, ret);
return;
}
ret = ifs->deleteObject(request, notificationId);
}
m_ddsHandler->fts()->deleteMessageReply(cookie, ret);
}
void HandlerNotification::onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType)
{
if (modType == DataModification::eAdded ||
(modType == DataModification::eModified && data.state != ExerciseManagement::ExerciseState::Stopped))
return;
// Remove notification for given exercise
QHashIterator<int, ObjectNotification*> it(m_objectNotificationMap);
while(it.hasNext())
{
it.next();
ObjectNotification* obj = it.value();
if (obj->notification().exerciseId != data.id)
continue;
DEBUG_LOG(m_logger) << "Remove notification " << obj->id();
Core::FunctionReplyObject ret = obj->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
else
{
// delete ObjectNotification
delete obj;
m_objectNotificationMap.remove(it.key());
}
}
}
void HandlerNotification::onCheckRemove()
{
QHashIterator<int, ObjectNotification*> it(m_objectNotificationMap);
while(it.hasNext())
{
it.next();
ObjectNotification* obj = it.value();
NomNotification notif = obj->notification();
if (!isRemoveable(notif))
continue;
DEBUG_LOG(m_logger) << "Remove notification " << obj->id();
Core::FunctionReplyObject ret = obj->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
else
{
// delete ObjectNotification
delete obj;
m_objectNotificationMap.remove(it.key());
}
}
}
bool HandlerNotification::isRemoveable(const NomNotification &notif)
{
// NomNotification from exercises will not be removed
if (notif.exerciseId != 0)
return false;
qint64 expiryInterval = Settings::expiryIntervalMSec();
qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
// Remove notification if expiryTime + expiryInterval / processTime + expiryInterval
if (currentTime > ( notif.expiryTime + expiryInterval) ||
(notif.processed > 0 && currentTime > ( notif.processTime + expiryInterval)))
return true;
return false;
}
} // namespace NotificationManagement