Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/Messaging/handler_operator_message.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

367 lines
14 KiB
C++
Executable File

/**
* Handler for message data request
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-12
*/
#include "handler_operator_message.h"
namespace Messaging
{
HandlerOperatorMessage::HandlerOperatorMessage(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DatabaseInterface> &db,
const std::shared_ptr<ExercisesHandler> &exercisesHandler,
QObject *parent)
: QObject(parent)
, CreateOperatorMessageRequestHandler(ddsHandler->fts())
, ModifyOperatorMessageRequestHandler(ddsHandler->fts())
, m_ddsHandler(ddsHandler)
, m_db(db)
, m_exercisesHandler(exercisesHandler)
, m_logger(getLogger("HandlerOperatorMessage"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool HandlerOperatorMessage::init()
{
INFO_LOG(m_logger) << "Start HandlerOperatorMessage.";
// read data from db-table 'msg_message_data'
// add to internal buffer
auto cbMsgData = [this] (const Database::MsgMessageData &data)
{
if (data.isDeleted)
return;
m_dbOperatorMessageData.insert(data.id, data);
m_ddsHandler->dts()->publish(toDdsData(data));
};
if (!m_db->select(cbMsgData)) // TODO (CE): nicht alle selektieren, nur die, die nicht gelöscht sind
{
ERROR_LOG(m_logger) << "Error reading data from database 'msg_message_data'!";
return false;
}
// Signal von tabDtc verbinden ( void equipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, DataModification modType))
// enableEquipmentMessage zum abbonieren der EquipmentMessages
// Alle derzeit vorhandenen Messages auslesen (equipmentMessages()) und verarbeiten
connect(m_exercisesHandler.get(), &ExercisesHandler::messageFromTrainingArea,
this, &HandlerOperatorMessage::onMesssageFromTrainingArea);
//OperatorManagement::Interface::Dtc
m_opmDtc = OperatorManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector());
// Operator Management to get Username from operator
connect(m_opmDtc.get(), &OperatorManagement::Interface::Dtc::userChanged,
this, &HandlerOperatorMessage::onOperatorChanged);
m_opmDtc->enableUser();
return true;
} // end of init()
//-----------------------------------------------------------------------------
void HandlerOperatorMessage::onCreateOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
const CreateOperatorMessageRequest &request)
{
DEBUG_LOG(m_logger) << "onCreateOperatorMessageRequest" << request;
auto ret = createOperatorMessageRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_ddsHandler->fts()->createOperatorMessageReply(cookie, ret);
}
Core::FunctionReplyObject HandlerOperatorMessage::createOperatorMessageRequest(const CreateOperatorMessageRequest &request)
{
// 1. In DB eintragen
// 2. publishen
// 3. in interne Verwaltung eintragen
// 4. mit ok antworten
Database::MsgMessageData newMsg;
newMsg.timeStamp = m_ddsHandler->currentPartitionTime();
newMsg.senderId = request.senderId;
INFO_LOG(m_logger) << "newMsg.senderId=" << newMsg.senderId;
newMsg.subject = QString::fromStdString(request.subject);
newMsg.message = QString::fromStdString(request.message);
newMsg.senderType = request.senderType;
INFO_LOG(m_logger) << "newMsg.senderType.underlying()=" << newMsg.senderType;
newMsg.senderText = toAddressStr(newMsg.senderType, newMsg.senderId, request.exerciseId);
newMsg.recipientType = request.recipientType;
newMsg.exerciseId = request.exerciseId;
QString recipientText;
for (int32_t i : request.recipientIds)
{
recipientText.append(toAddressStr(newMsg.recipientType, i, newMsg.exerciseId));
recipientText.append(QString::fromStdString(" "));
}
newMsg.isRead = false;
newMsg.isDeleted = false;
INFO_LOG(m_logger) << "newMsg.senderType=" << newMsg.senderType << " newMsg.receiverType=" << newMsg.recipientType;
// Insert message for sender
newMsg.recipientId = 0;
newMsg.recipientText = recipientText;
// Only Operator messages
Core::FunctionReplyObject ret(newMsg.id);
if (newMsg.senderType == Messaging::AddressType::type::Operator)
ret = insertInDbAndPublish(newMsg);
const int correspondingOutboxMsgId = ret.id();
if (!ret.error() )
{
INFO_LOG(m_logger) << "insert message for each receiver";
// Insert message for each receiver
//newMsg.senderId = 0; WHY?
//if (correspondingOutboxMsgId > 0) // messages received from TETRA dont have a corresponding outbox id
newMsg.correspondingOutboxMessageId = correspondingOutboxMsgId; // can be also 0 - from TETRA
for (const auto recipientId : request.recipientIds)
{
newMsg.recipientId = recipientId;
newMsg.recipientText = toAddressStr(newMsg.recipientType, newMsg.recipientId, newMsg.exerciseId);
INFO_LOG(m_logger) << "recipientId: " << newMsg.recipientId;
ret = insertInDbAndPublish(newMsg);
if (ret.error())
break;
}
}
if (ret.error())
WARNING_LOG(m_logger) << ret();
return ret;
} // end of onCreateOperatorMessageRequest()
//-----------------------------------------------------------------------------
void HandlerOperatorMessage::onModifyOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
const ModifyOperatorMessageRequest &request)
{
// 1. schauen ob es diese Message überhaupt gibt
// 2. aktualisieren in DB
// 3. interne Verwaltung aktualisieren
// 4. neu publishen bzw. von dds löschen
// 5. mit ok antworten
auto it = m_dbOperatorMessageData.find(request.id);
if (it == m_dbOperatorMessageData.end())
{
const auto ret = Core::FunctionReplyObject(0, tr_lts("dds", "Could not find message with id %1")).arg(request.id);
m_ddsHandler->fts()->modifyOperatorMessageReply(cookie, ret);
return;
}
Database::MsgMessageData data = it.value();
data.isDeleted = request.isDeleted;
data.isSend = request.isSend;
data.isRead = request.isRead;
const auto ret = modifyDbAndPublish(data);
m_ddsHandler->fts()->modifyOperatorMessageReply(cookie, ret);
} // end of onModifyOperatorMessageRequest()
//-----------------------------------------------------------------------------
OperatorMessage HandlerOperatorMessage::toDdsData(const Database::MsgMessageData &dbData)
{
OperatorMessage ddsData;
ddsData.id = dbData.id;
ddsData.senderId = dbData.senderId;
ddsData.recipientId = dbData.recipientId;
ddsData.exerciseId = dbData.exerciseId;
ddsData.subject = dbData.subject.toStdString();
ddsData.message = dbData.message.toStdString();
ddsData.recipientText = dbData.recipientText.toStdString();
ddsData.senderText = dbData.senderText.toStdString();
ddsData.isRead = dbData.isRead;
ddsData.isSend = dbData.isSend;
ddsData.isDeleted = dbData.isDeleted;
ddsData.senderType = dbData.senderType;
ddsData.recipientType = dbData.recipientType;
ddsData.correspondingOutboxMessageId = dbData.correspondingOutboxMessageId; // can also be 0
ddsData.timeStamp = dbData.timeStamp;
return ddsData;
} // end of toDdsData()
//-----------------------------------------------------------------------------
// Insert in db and publish
Core::FunctionReplyObject HandlerOperatorMessage::insertInDbAndPublish(Database::MsgMessageData newMsg)
{
// Length Check:
if (newMsg.recipientType == Messaging::AddressType::type::ObserverController)
{
newMsg.subject = newMsg.subject.left(m_maxSubjectLength);
newMsg.message = newMsg.message.left(m_maxOcContentLength);
}
if (newMsg.recipientType == Messaging::AddressType::type::Participant)
{
newMsg.subject = newMsg.subject.left(m_maxSubjectLength);
newMsg.message.clear();
}
DEBUG_LOG(m_logger) << "newMsg.senderId = " << newMsg.senderId;
if (!m_db->insert(newMsg))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding message to database"));
m_dbOperatorMessageData.insert(newMsg.id, newMsg);
if ((newMsg.recipientType == Messaging::AddressType::type::ObserverController)
|| (newMsg.recipientType == Messaging::AddressType::type::Participant))
{
int32_t equipmentNumber = m_exercisesHandler->findEquipmentNumber(newMsg.recipientId, newMsg.exerciseId);
int32_t participantId = newMsg.recipientId;
INFO_LOG(m_logger) << "equipmentNumber: " << equipmentNumber << ", participantId: " << participantId << ", exerciseId: " << newMsg.exerciseId;
// Length Check:
const auto subject = newMsg.subject.toStdString();
const auto message = newMsg.message.toStdString();
INFO_LOG(m_logger) << "Message to OC: subject =" << subject << " Message =" << message;
// only send to Tetra:
if (newMsg.recipientId > 0)
{
int senderId = m_dbOperatorMessageData[newMsg.correspondingOutboxMessageId].senderId;
AddressType senderType = m_dbOperatorMessageData[newMsg.correspondingOutboxMessageId].senderType;
INFO_LOG(m_logger) << "SendEquipmentMessageRequest id =" << newMsg.id;
INFO_LOG(m_logger) << " equipmentNumber=" << equipmentNumber
<< " participantId=" << participantId
<< " newMsg.id=" << newMsg.id
<< " newMsg.senderId=" << senderId
<< " newMsg.adressType=" << senderType
<< " subject=" << subject
<< " message=" << message;
static int s_requestId = 1;
if (newMsg.recipientType == Messaging::AddressType::type::ObserverController)
{
INFO_LOG(m_logger) << "Send to OC senderId=" << newMsg.senderId << " sendertype: " << newMsg.senderType << " subject " << subject;
m_exercisesHandler->sendOcEquipmentMessage({s_requestId++,
{equipmentNumber},
//newMsg.id,
newMsg.senderId,
newMsg.senderType,
subject,
message
});
}
else
{
m_exercisesHandler->sendEquipmentMessage({s_requestId++,
{equipmentNumber},
newMsg.id,
senderId,
subject,
message
});
}
}
//m_ddsHandler->tabFtc()->sendEquipmentMessageRequest(...);
//onsendEquipmentMessageReply implementieren und dort gelesen = true;
}
m_ddsHandler->dts()->publish(toDdsData(newMsg));
INFO_LOG(m_logger) << "insertInDbAndPublish id=" << newMsg.id;
if (newMsg.recipientType == Messaging::AddressType::type::ObserverController && newMsg.recipientId > 0)
{
INFO_LOG(m_logger) << "O/C-Message in Member-Variable kopieren: id = " << newMsg.id;
}
return Core::FunctionReplyObject(newMsg.id);
} // end of insertInDbAndPublish()
// Modify db and publish
Core::FunctionReplyObject HandlerOperatorMessage::modifyDbAndPublish(const Database::MsgMessageData &modMsg)
{
INFO_LOG(m_logger) << "modifyDbAndPublish" << " id=" << modMsg.id <<
" isDeleted=" << modMsg.isDeleted <<
" modMsg.isRead=" << modMsg.isRead <<
" modMsg.isSend=" << modMsg.isSend <<
" modMsg.sender=" << modMsg.senderId <<
" modMsg.receiver=" << modMsg.recipientId;
if (!m_db->update(modMsg))
return Core::FunctionReplyObject(modMsg.id,
tr_lts("dds", "Error updating message with id %1 to database")).arg(modMsg.id);
m_dbOperatorMessageData[modMsg.id] = modMsg;
if (modMsg.isDeleted)
{
INFO_LOG(m_logger) << "Remove LTS_OperatorMessage from DDS id=" << modMsg.id;
m_ddsHandler->dts()->removeOperatorMessageByKey(modMsg.id);
}
else
m_ddsHandler->dts()->publish(toDdsData(modMsg));
return Core::FunctionReplyObject(modMsg.id);
} // end of modifyDbAndPublish()
// Receive from Tetra
void HandlerOperatorMessage::onMesssageFromTrainingArea(const TrainingAreaBase::EquipmentMessage &data)
{
INFO_LOG(m_logger) << "************ onMesssageFromTrainingArea ********************";
onEquipmentMessageChanged(data, DataModification::eAdded);
}
// Receive from Tetra
void HandlerOperatorMessage::onEquipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, const DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
CreateOperatorMessageRequest request;
DEBUG_LOG(m_logger) << "onEquipmentMessageChanged: " << data;
request.senderType = Messaging::AddressType::type::Participant;
request.senderId = data.sender;
DEBUG_LOG(m_logger) << "request.senderId = " << request.senderId;
request.recipientType = Messaging::AddressType::type::Operator;
request.recipientIds.push_back(data.receiver);
request.subject = data.subject;
request.message = data.text;
createOperatorMessageRequest(request);
// Todo Fragen, ob die Meldung vom DDS geloescht werden soll.
} // end of onEquipmentMessageChanged
void HandlerOperatorMessage::onOperatorChanged(const OperatorManagement::User &data)
{
DEBUG_LOG(m_logger) << "************** onOperatorChanged ";
m_operatorMap.insert(data.id, data.name);
} // end of onOperatorChanged
QString HandlerOperatorMessage::toAddressStr(const AddressType addressType, const qint32 addressId, int exerciseId)
{
QString result;
switch (addressType)
{
case AddressType::Operator:
// nicht per Request sondern hier aus OPM holen
result = QString::fromStdString(m_operatorMap.value(addressId, "Unknown Operator"));
break;
case AddressType::ObserverController:
{
int equipNumber = m_exercisesHandler->findEquipmentNumber(addressId, exerciseId);
if (equipNumber > 0)
result += QStringLiteral(" - ") + QString::number(equipNumber);
break;
}
case AddressType::Participant:
result = QLatin1String("Participant:") + QString::number(addressId);
break;
default:
result = QString::fromStdString("No valid addressType:");
QString numberStr ;
numberStr.setNum(addressType);
result.append(numberStr);
}
return result;
} // end of toAddressStr
} // namespace Messaging