686 lines
24 KiB
C++
Executable File
686 lines
24 KiB
C++
Executable File
/**
|
|
* Handler for all exercise objects
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Hanna E. Rathje, SLSE, 2015-09-03
|
|
*/
|
|
|
|
#include "handler_operator.h"
|
|
#include "handler_locked_topics.h"
|
|
#include "handler_active_apps.h"
|
|
#include "object_operator.h"
|
|
#include "handler_group.h"
|
|
#include "opm_db.h"
|
|
#include <QCryptographicHash>
|
|
#include <QSet>
|
|
#include <QTimer>
|
|
#include <LtsUtilsCore/dds_vector.h>
|
|
|
|
namespace OperatorManagement
|
|
{
|
|
|
|
HandlerOperator::HandlerOperator(MainHandler *mainHandler)
|
|
: Interface::Fts::OperatorChangePasswordRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorCreateModifyRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorRemoveRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorLoginRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorLogoutRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorGetSetSettingsRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorApplyForeignAclsRequestHandler(mainHandler->fts())
|
|
, Interface::Fts::OperatorUpdateVisiblePartiesByExerciseRequestHandler(mainHandler->fts())
|
|
, m_aliveCheckTimer(new QTimer(this))
|
|
, m_mainHandler(mainHandler)
|
|
, m_logger(getLogger("HandlerOperator"))
|
|
{
|
|
connect(m_aliveCheckTimer, &QTimer::timeout, this, &HandlerOperator::onCheckAliveTimeout);
|
|
m_aliveCheckTimer->setInterval(10000);
|
|
m_aliveCheckTimer->setSingleShot(false);
|
|
m_aliveCheckTimer->start();
|
|
}
|
|
|
|
HandlerOperator::~HandlerOperator()
|
|
{
|
|
qDeleteAll(m_operatorObjMap);
|
|
}
|
|
|
|
bool HandlerOperator::init()
|
|
{
|
|
QVector<Database::OpmOperatorExercise> exMappingVec;
|
|
m_mainHandler->db()->select(exMappingVec);
|
|
|
|
QVector<Database::OpmOperator> dataVec;
|
|
// read all Operators from database
|
|
if (!m_mainHandler->db()->select(dataVec))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error reading data from database!";
|
|
return true;
|
|
}
|
|
|
|
QVector<Database::OpmOperatorExercise> partyExerciseVec;
|
|
// read all Operators from database
|
|
if (!m_mainHandler->db()->select(partyExerciseVec))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error reading data from database!";
|
|
return true;
|
|
}
|
|
QMap<int, QVector<Database::OpmOperatorExercise> > opMap;
|
|
for (const auto &elem : partyExerciseVec)
|
|
{
|
|
INFO_LOG(m_logger) << "---------- elem.operatorId:" << elem.operatorId
|
|
<< ", elem size " << elem.visibleParties().size();
|
|
opMap[elem.operatorId] << elem;
|
|
}
|
|
INFO_LOG(m_logger) << "------- opMap size" << opMap.size();
|
|
|
|
OperatorManagement::OperatorWorkstationAlive alive;
|
|
alive.lastAlive(QDateTime::currentMSecsSinceEpoch());
|
|
for (const Database::OpmOperator &op : qAsConst(dataVec))
|
|
{
|
|
ObjectOperator *ifs(new ObjectOperator(m_mainHandler));
|
|
Core::FunctionReplyObject ret = ifs->createObject(op, opMap[op.id]);
|
|
if (ret.error())
|
|
{
|
|
delete ifs;
|
|
ERROR_LOG(m_logger) << ret();
|
|
return false;
|
|
}
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
QStringList stringList;
|
|
const auto &acls = ifs->effectiveAcls();
|
|
stringList.reserve(acls.size());
|
|
for (int acl : acls)
|
|
stringList << QString::number(acl);
|
|
DEBUG_LOG(m_logger) << "Effective ACLs for Operator " << op.name << "(id: " << op.id << "): "
|
|
<< stringList.join(QLatin1String(", "));
|
|
}
|
|
ifs->updateExercises(getExercisesForOperator(exMappingVec, op.id), true);
|
|
m_operatorObjMap.insert(ifs->getId(), ifs);
|
|
if (!op.workstationId.isNull())
|
|
{
|
|
alive.operatorId(op.id);
|
|
alive.workstationId(op.workstationId.toInt());
|
|
onOperatorWorkstationAliveChanged(alive, DataModification::eAdded);
|
|
}
|
|
}
|
|
|
|
auto dtc = m_mainHandler->dtc();
|
|
connect(dtc.get(), &Interface::Dtc::operatorWorkstationAliveChanged,
|
|
this, &HandlerOperator::onOperatorWorkstationAliveChanged);
|
|
dtc->enableOperatorWorkstationAlive();
|
|
|
|
DEBUG_LOG(m_logger) << "m_exeObjMap.size() = " << m_operatorObjMap.size();
|
|
|
|
return true;
|
|
}
|
|
|
|
QString HandlerOperator::operatorNameById(int operatorId) const
|
|
{
|
|
ObjectOperator *obj = m_operatorObjMap.value(operatorId);
|
|
if (!obj)
|
|
return QStringLiteral("?");
|
|
return obj->data().name;
|
|
}
|
|
|
|
|
|
std::vector<int> HandlerOperator::getExercisesForOperator(const QVector<Database::OpmOperatorExercise> &mapping, int operatorId)
|
|
{
|
|
std::vector<int> exercises;
|
|
|
|
for (const Database::OpmOperatorExercise &exMapping : mapping)
|
|
if (exMapping.operatorId == operatorId)
|
|
exercises.push_back(exMapping.exerciseId);
|
|
|
|
return exercises;
|
|
}
|
|
|
|
void HandlerOperator::onOperatorChangePasswordRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorChangePasswordRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onOperatorChangePasswordRequest()";
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (!ifs)
|
|
{
|
|
m_mainHandler->fts()->operatorChangePasswordReply(cookie,
|
|
Core::FunctionReplyObject(0, tr_lts("dds", "No valid operator id for changing password.")));
|
|
return;
|
|
}
|
|
|
|
Core::FunctionReplyObject ret;
|
|
Database::OpmOperator op = ifs->data();
|
|
|
|
const auto &pw = request.oldPassword();
|
|
const QByteArray ba(QByteArray::fromRawData(pw.c_str(), pw.size()));
|
|
const QString enteredPassword(QString::fromLatin1(QCryptographicHash::hash(ba, QCryptographicHash::Md5).toHex()));
|
|
|
|
const auto &pwNew = request.password();
|
|
const QByteArray baNew(QByteArray::fromRawData(pwNew.c_str(), pwNew.size()));
|
|
const QString enteredPasswordNew(QString::fromLatin1(QCryptographicHash::hash(baNew, QCryptographicHash::Md5).toHex()));
|
|
|
|
if (request.forceSet() || op.password == enteredPassword)
|
|
{
|
|
if (enteredPassword == enteredPasswordNew)
|
|
ret = Core::FunctionReplyObject(0, tr_lts("dds", "Password is identical to old password."));
|
|
// else if (request.password().size() < n && $minimum1digit && minimum1extrachar && ...)
|
|
// {
|
|
// ret = Core::FunctionReplyObject(0, tr_lts("dds", "Password must be at least n characters"));
|
|
// }
|
|
else
|
|
{
|
|
op.password = enteredPasswordNew;
|
|
ret = ifs->updateObject(op);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = Core::FunctionReplyObject(0, tr_lts("dds", "Old password does not match."));
|
|
}
|
|
|
|
m_mainHandler->fts()->operatorChangePasswordReply(cookie, ret);
|
|
}
|
|
|
|
void HandlerOperator::onOperatorCreateModifyRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorCreateModifyRequest &request)
|
|
{
|
|
Core::FunctionReplyObject ret;
|
|
DEBUG_LOG(m_logger) << "onOperatorCreateModifyRequest()";
|
|
if (!request.id().is_set())
|
|
ret = operatorCreateRequest(request);
|
|
else
|
|
ret = operatorModifyRequest(request);
|
|
|
|
if (ret.error())
|
|
WARNING_LOG(m_logger) << ret();
|
|
m_mainHandler->fts()->operatorCreateModifyReply(cookie, ret);
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerOperator::operatorCreateRequest(const OperatorCreateModifyRequest &request)
|
|
{
|
|
if (!request.name().is_set() ||
|
|
!request.password().is_set())
|
|
return Core::FunctionReplyObject(tr_lts("dds", "Can not create operator - name or password is empty."));
|
|
|
|
// Group anlegen
|
|
GroupCreateRequest groupRequest;
|
|
groupRequest.name(request.name().get());
|
|
groupRequest.description(request.description().get());
|
|
groupRequest.type(GroupType_def::OperatorGroup);
|
|
|
|
const Core::FunctionReplyObject groupRet = m_mainHandler->getHandlerGroup()->create(groupRequest);
|
|
if (groupRet.error())
|
|
return groupRet;
|
|
|
|
// Operator anlegen
|
|
Database::OpmOperator op;
|
|
op.name = QString::fromStdString(request.name().get());
|
|
if (request.description().is_set())
|
|
op.description = QString::fromStdString(request.description().get());
|
|
|
|
|
|
const auto &pw = request.password().get();
|
|
const QByteArray ba(QByteArray::fromRawData(pw.c_str(), pw.size()));
|
|
const QString enteredPassword(QString::fromLatin1(QCryptographicHash::hash(ba, QCryptographicHash::Md5).toHex()));
|
|
|
|
op.password = enteredPassword;
|
|
op.primaryGroupId = groupRet.id();
|
|
if (request.image().is_set())
|
|
op.image = LtsUtils::toQByteArray(request.image().get());
|
|
const auto vpbe = request.visiblePartiesByExercise();
|
|
for (const auto &pbe : vpbe)
|
|
{
|
|
if (!pbe.visibleParties().is_set() || pbe.exerciseId() != 0) //has_value not support on windows yet so we need depricated is_set
|
|
continue;
|
|
|
|
op.visibleParties = LtsUtils::IntArray(pbe.visibleParties().get());
|
|
}
|
|
if (request.rolePresetId().is_set())
|
|
{
|
|
op.rolePresetId = request.rolePresetId().get();
|
|
}
|
|
op.projectionPriority = request.projectionPriority().is_set() ? request.projectionPriority().get() : 1;
|
|
op.audioChannelPriority = request.audioChannelPriority().is_set() ? request.audioChannelPriority().get() : 1;
|
|
|
|
ObjectOperator *ifs(new ObjectOperator(m_mainHandler));
|
|
const Core::FunctionReplyObject ret = ifs->createObject(op, {});
|
|
if (ret.error())
|
|
{
|
|
Core::RemoveElementRequest groupRemoveRequest(groupRet.id());
|
|
m_mainHandler->getHandlerGroup()->remove(groupRemoveRequest);
|
|
delete ifs;
|
|
return ret;
|
|
}
|
|
if (request.visibleExercises().is_set())
|
|
ifs->updateExercises(request.visibleExercises().get());
|
|
|
|
if (request.operatorRights().is_set())
|
|
{
|
|
GroupChangeMembersRequest grChReq;
|
|
grChReq.id(op.primaryGroupId);
|
|
grChReq.memberships(request.operatorRights().get());
|
|
// We don't actually care, if this fails...
|
|
m_mainHandler->getHandlerGroup()->changeMembership(grChReq);
|
|
ifs->reloadAcls(true);
|
|
}
|
|
m_operatorObjMap.insert(ifs->getId(), ifs);
|
|
return ret;
|
|
}
|
|
|
|
void HandlerOperator::operatorModifyRolePresetId( int operatorId, int rolePresetId)
|
|
{
|
|
DEBUG_LOG(m_logger)<< "HandlerOperator::operatorModifyRolePresetId"
|
|
<< " operatorId=" << operatorId
|
|
<< " rolePresetId=" << rolePresetId;
|
|
ObjectOperator *ifs = m_operatorObjMap.value(operatorId);
|
|
if (!ifs)
|
|
{
|
|
ERROR_LOG(m_logger)<< "No valid operator id given: "<< operatorId;
|
|
return;
|
|
}
|
|
|
|
Database::OpmOperator op = ifs->data();
|
|
op.rolePresetId = rolePresetId;
|
|
|
|
ifs->updateObject(op);
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerOperator::operatorModifyRequest(const OperatorCreateModifyRequest &request)
|
|
{
|
|
if (request.password().is_set())
|
|
return Core::FunctionReplyObject(tr_lts("dds", "Can not modify operator password with this function."));
|
|
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id().get());
|
|
if (!ifs)
|
|
return Core::FunctionReplyObject(request.id().get(), tr_lts("dds", "No valid operator id given."));
|
|
|
|
Database::OpmOperator op = ifs->data();
|
|
|
|
if (request.name().is_set())
|
|
{
|
|
op.name = QString::fromStdString(request.name().get());
|
|
|
|
for (const ObjectOperator *o : qAsConst(m_operatorObjMap))
|
|
{
|
|
if (o == ifs)
|
|
continue;
|
|
if (o->name().compare(op.name, Qt::CaseInsensitive) == 0)
|
|
return Core::FunctionReplyObject(-1, tr_lts("dds", "Name '%1' already exists")).arg(op.name);
|
|
}
|
|
}
|
|
|
|
if (request.description().is_set())
|
|
op.description = QString::fromStdString(request.description().get());
|
|
if (request.image().is_set())
|
|
op.image = LtsUtils::toQByteArray(request.image().get());
|
|
const auto vpbe = request.visiblePartiesByExercise();
|
|
for (const auto &pbe : vpbe)
|
|
{
|
|
// only ex0 updated
|
|
if (!pbe.visibleParties().is_set() || pbe.exerciseId() != 0) //has_value not support on windows yet so we need depricated is_set
|
|
continue;
|
|
|
|
op.visibleParties = LtsUtils::IntArray(pbe.visibleParties().get());
|
|
}
|
|
|
|
if (request.rolePresetId().is_set())
|
|
{
|
|
op.rolePresetId = request.rolePresetId().get();
|
|
}
|
|
|
|
if (request.visibleExercises().is_set())
|
|
ifs->updateExercises(request.visibleExercises().get());
|
|
if (request.projectionPriority().is_set())
|
|
op.projectionPriority = request.projectionPriority().get();
|
|
if (request.audioChannelPriority().is_set())
|
|
op.audioChannelPriority = request.audioChannelPriority().get();
|
|
op.properties = QString::fromStdString(request.properties());
|
|
|
|
return ifs->updateObject(op);
|
|
}
|
|
|
|
void HandlerOperator::onOperatorRemoveRequest(const rti::core::SampleIdentity &cookie,
|
|
const Core::RemoveElementRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onOperatorRemoveRequest()" << request;
|
|
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (!ifs)
|
|
{
|
|
m_mainHandler->fts()->operatorRemoveReply(cookie,
|
|
Core::FunctionReplyObject(0, tr_lts("dds", "No valid operator id for deleting.")));
|
|
return;
|
|
}
|
|
|
|
if (!ifs->data().workstationId.isNull())
|
|
{
|
|
m_mainHandler->fts()->operatorRemoveReply(cookie,
|
|
Core::FunctionReplyObject(0, tr_lts("dds", "A logged in operator may not be deleted.")));
|
|
return;
|
|
}
|
|
|
|
OperatorManagement::User ddsData;
|
|
ddsData.id(request.id());
|
|
|
|
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ddsData, 0))
|
|
{
|
|
m_mainHandler->fts()->operatorRemoveReply(cookie,
|
|
Core::FunctionReplyObject(request.id(), tr_lts("dds", "Operator '%1' is used by another user!")).arg(ifs->name()));
|
|
return;
|
|
}
|
|
|
|
Core::RemoveElementRequest groupRemoveRequest(ifs->data().primaryGroupId);
|
|
Core::FunctionReplyObject ret = m_mainHandler->getHandlerGroup()->remove(groupRemoveRequest);
|
|
if (ret.error())
|
|
{
|
|
ERROR_LOG(m_logger) << ret();
|
|
}
|
|
else
|
|
{
|
|
ret = ifs->removeObject();
|
|
// Aus der lokalen Map löschen
|
|
m_operatorObjMap.remove(ifs->getId());
|
|
// und aus TopicLock entfernen
|
|
m_mainHandler->getHandlerLockedTopics()->operatorLoggedOut(ifs->getId());
|
|
delete ifs;
|
|
}
|
|
m_mainHandler->fts()->operatorRemoveReply(cookie, ret);
|
|
}
|
|
|
|
void HandlerOperator::onOperatorLoginRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorLoginRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "OperatorLoginRequest: " << request;
|
|
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (!ifs)
|
|
{
|
|
m_mainHandler->fts()->operatorLoginReply(cookie,
|
|
Core::FunctionReplyObject(0, tr_lts("dds", "No operator found by the given id.")));
|
|
return;
|
|
}
|
|
|
|
const auto &pw = request.password();
|
|
const QByteArray ba(QByteArray::fromRawData(pw.c_str(), pw.size()));
|
|
const QString enteredPassword(QString::fromLatin1(QCryptographicHash::hash(ba, QCryptographicHash::Md5).toHex()));
|
|
if (enteredPassword != ifs->data().password)
|
|
{
|
|
m_mainHandler->fts()->operatorLoginReply(cookie,
|
|
Core::FunctionReplyObject(ifs->data().workstationId.toInt(), tr_lts("dds", "The password you have entered is invalid.")));
|
|
return;
|
|
}
|
|
// If no WS is claimed, just return operator ID
|
|
Core::FunctionReplyObject ret(ifs->data().id);
|
|
|
|
// Request claim a WS
|
|
if (!ifs->data().workstationId.isNull() && ifs->data().workstationId.toInt() > 0)
|
|
// operator already logged in
|
|
{
|
|
if (ifs->data().workstationId == request.workstationId())
|
|
{
|
|
// do nothing if same operator claims same workstation
|
|
}
|
|
else if (!request.force())
|
|
{
|
|
// Already claimed: Return WSid as ID
|
|
const auto ws = m_mainHandler->dds()->dtcAsm()->asset(ifs->data().workstationId.toInt());
|
|
ret = Core::FunctionReplyObject(ifs->data().workstationId.toInt(),
|
|
tr_lts("dds", "Operator already logged in on workstation %1.")).arg(QString::fromStdString(ws.name()));
|
|
}
|
|
else
|
|
{
|
|
// force login, logout the other operator logged in on this WS, if there is any
|
|
int otherOperatorId = getLoggedOperatorId(ifs->data().workstationId.toInt());
|
|
if (otherOperatorId != 0 && otherOperatorId != ifs->data().id)
|
|
{
|
|
ObjectOperator *other = m_operatorObjMap.value(otherOperatorId);
|
|
if (other)
|
|
{
|
|
OperatorLogoutRequest req;
|
|
req.id(otherOperatorId);
|
|
onOperatorLogoutRequest(cookie, req);
|
|
}
|
|
}
|
|
Database::OpmOperator op = ifs->data();
|
|
op.workstationIp = request.workstationIp();
|
|
op.workstationId = request.workstationId();
|
|
ret = ifs->updateObject(op);
|
|
}
|
|
}
|
|
else
|
|
// operator not logged in on any workstation
|
|
{
|
|
// if other operator is logged in on same WS -> logout other operator and login our operator
|
|
int otherOperatorId = getLoggedOperatorId(request.workstationId());
|
|
|
|
if (otherOperatorId != 0 && otherOperatorId != ifs->data().id)
|
|
{
|
|
ObjectOperator *other = m_operatorObjMap.value(otherOperatorId);
|
|
if (other)
|
|
{
|
|
OperatorLogoutRequest req;
|
|
req.id(otherOperatorId);
|
|
onOperatorLogoutRequest(cookie, req);
|
|
WARNING_LOG(m_logger) << "Logged out operator " << otherOperatorId << " on workstation id " << request.workstationId();
|
|
}
|
|
}
|
|
// Claim WS:
|
|
Database::OpmOperator op = ifs->data();
|
|
op.workstationIp = request.workstationIp();
|
|
op.workstationId = request.workstationId();
|
|
ret = ifs->updateObject(op);
|
|
}
|
|
|
|
if (ret.error())
|
|
WARNING_LOG(m_logger) << ret();
|
|
else
|
|
{
|
|
m_mainHandler->getHandlerLockedTopics()->operatorLoggedIn(request.id(), request.workstationId());
|
|
m_mainHandler->getHandlerActiveApps()->cleanupOperator(request.id());
|
|
}
|
|
|
|
m_mainHandler->fts()->operatorLoginReply(cookie, ret);
|
|
}
|
|
|
|
int HandlerOperator::getLoggedOperatorId(int workstationId) const
|
|
{
|
|
auto it = std::find_if(m_operatorObjMap.begin(), m_operatorObjMap.end(),
|
|
[workstationId](const ObjectOperator *oper) { return oper->data().workstationId == workstationId; });
|
|
return (it == m_operatorObjMap.end() ? 0 : it.value()->getId());
|
|
}
|
|
|
|
void HandlerOperator::onOperatorLogoutRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorLogoutRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "OperatorLogoutRequest: " << request;
|
|
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (!ifs)
|
|
{
|
|
m_mainHandler->fts()->operatorLogoutReply(cookie, Core::FunctionReplyObject(0, tr_lts("dds", "No valid operator id for logout.")));
|
|
return;
|
|
}
|
|
|
|
if (ifs->data().workstationId.isNull() || ifs->data().workstationId == 0) // && ifs->data().workstationIp == 0 ?
|
|
{
|
|
m_mainHandler->fts()->operatorLogoutReply(cookie, Core::FunctionReplyObject(ifs->data().id));
|
|
return;
|
|
}
|
|
Database::OpmOperator op = ifs->data();
|
|
op.workstationIp = 0;
|
|
op.workstationId = QVariant();
|
|
|
|
m_mainHandler->getHandlerLockedTopics()->operatorLoggedOut(request.id()); // workstationId = 0 -> logout
|
|
m_mainHandler->getHandlerActiveApps()->cleanupOperator(op.id);
|
|
|
|
m_mainHandler->fts()->operatorLogoutReply(cookie, ifs->updateObject(op));
|
|
}
|
|
|
|
void HandlerOperator::onOperatorGetSetSettingsRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorGetSetSettingsRequest &request)
|
|
{
|
|
Core::FunctionReplyObject fro;
|
|
OperatorGetSetSettingsReply reply;
|
|
reply.id(request.id());
|
|
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (ifs)
|
|
{
|
|
if (request.settings().is_set())
|
|
{
|
|
const auto &data = request.settings().get();
|
|
const QByteArray settings(QByteArray(reinterpret_cast<const char*>(&data[0]), data.size()));
|
|
if (!ifs->saveSettings(settings))
|
|
fro = Core::FunctionReplyObject(request.id(), tr_lts("dds", "Error saving settings in database.") );
|
|
}
|
|
else
|
|
{
|
|
QByteArray settings;
|
|
if (!ifs->loadSettings(settings))
|
|
{
|
|
fro = Core::FunctionReplyObject(request.id(), tr_lts("dds", "Error loading settings from database.") );
|
|
}
|
|
else
|
|
{
|
|
if (!settings.isEmpty())
|
|
{
|
|
reply.settings().set({});
|
|
reply.settings().get() = LtsUtils::convert<std::vector<uint8_t>>(settings);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fro = Core::FunctionReplyObject(request.id(), tr_lts("dds", "No valid operator id for retrieving settings."));
|
|
}
|
|
|
|
if (fro.error())
|
|
{
|
|
reply.id(fro.id());
|
|
reply.errorString(fro.str());
|
|
reply.errorParams(fro.args());
|
|
}
|
|
|
|
m_mainHandler->fts()->operatorGetSetSettingsReply(cookie, reply);
|
|
}
|
|
|
|
void HandlerOperator::onOperatorApplyForeignAclsRequest(const rti::core::SampleIdentity &cookie, const OperatorApplyForeignAclsRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "peratorApplyForeignAclsRequest: " << request;
|
|
auto reply = operatorApplyForeignAclsRequest(request);
|
|
if (reply.error())
|
|
WARNING_LOG(m_logger) << reply();
|
|
m_mainHandler->fts()->operatorApplyForeignAclsReply(cookie, reply);
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerOperator::operatorApplyForeignAclsRequest(const OperatorApplyForeignAclsRequest &request)
|
|
{
|
|
ObjectOperator *receiver = m_operatorObjMap.value(request.id());
|
|
if (!receiver)
|
|
return Core::FunctionReplyObject(0, tr_lts("dds", "Receiving operator not present."));
|
|
|
|
ObjectOperator *remoteOperator = m_operatorObjMap.value(request.remoteOperatorId());
|
|
if (!remoteOperator)
|
|
return Core::FunctionReplyObject(0, tr_lts("dds", "Remote operator not present."));
|
|
|
|
return receiver->setPrimaryGroupId(remoteOperator->data().primaryGroupId);
|
|
}
|
|
|
|
void HandlerOperator::onOperatorUpdateVisiblePartiesByExerciseRequest(const rti::core::SampleIdentity &cookie,
|
|
const OperatorUpdateVisiblePartiesByExerciseRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << request;
|
|
// DEBUG_LOG(m_logger) << "onOperatorUpdateVisiblePartiesByExerciseRequest: " << request;
|
|
Core::FunctionReplyObject reply = operatorUpdateVisiblePartiesByExerciseRequest(request);
|
|
if (reply.error())
|
|
WARNING_LOG(m_logger) << reply();
|
|
m_mainHandler->fts()->operatorUpdateVisiblePartiesByExerciseReply(cookie, reply);
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerOperator::operatorUpdateVisiblePartiesByExerciseRequest(const OperatorUpdateVisiblePartiesByExerciseRequest &request)
|
|
{
|
|
ObjectOperator *ifs = m_operatorObjMap.value(request.id());
|
|
if (!ifs)
|
|
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "No valid operator id given."));
|
|
|
|
Database::OpmOperatorExercise opEx;
|
|
opEx.operatorId = request.id();
|
|
opEx.exerciseId = request.exerciseId();
|
|
std::vector<int> hiddenParties;
|
|
if (request.hiddenParties().is_set())
|
|
opEx.hiddenParties = LtsUtils::IntArray(request.hiddenParties().get());
|
|
if (request.visibleParties().is_set())
|
|
opEx.visibleParties = LtsUtils::IntArray(request.visibleParties().get());
|
|
|
|
opEx.properties = QString::fromStdString(request.properties());
|
|
|
|
return ifs->updateOperatorExercise(opEx);
|
|
}
|
|
|
|
void HandlerOperator::reloadAcls()
|
|
{
|
|
for (ObjectOperator *ifs : qAsConst(m_operatorObjMap))
|
|
ifs->reloadAcls();
|
|
}
|
|
|
|
void HandlerOperator::onOperatorWorkstationAliveChanged(const OperatorManagement::OperatorWorkstationAlive &data, DataModification modType)
|
|
{
|
|
INFO_LOG(m_logger) << "onOperatorWorkstationAliveChanged: " << data << ", " << modType;
|
|
if (data.operatorId() < 0)
|
|
{
|
|
m_aliveData.remove(data.workstationId());
|
|
return;
|
|
}
|
|
|
|
auto &events = m_aliveData[data.workstationId()];
|
|
events.push_back(data);
|
|
// do not store more than 30 history events
|
|
if (events.size() > 30)
|
|
events = events.mid(10);
|
|
}
|
|
|
|
void HandlerOperator::onCheckAliveTimeout()
|
|
{
|
|
if (m_aliveData.isEmpty())
|
|
return;
|
|
|
|
const qint64 tTimeoutTime = QDateTime::currentMSecsSinceEpoch() - 90 * 1000; // 90s
|
|
DEBUG_LOG(m_logger) << "onCheckAliveTimeout, timeoutTime: " << tTimeoutTime;
|
|
auto it = m_aliveData.begin();
|
|
while (it != m_aliveData.end())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Checking alive for workstation " << it.key();
|
|
auto &events = it.value();
|
|
if (events.isEmpty() || events.last().lastAlive() >= tTimeoutTime)
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
// no reference, will be a dangling one after m_aliveData.erase(it) !
|
|
const OperatorWorkstationAlive owa = events.last();
|
|
|
|
WARNING_LOG(m_logger) << "Timeout for workstation " << owa.workstationId()
|
|
<< " and operator " << owa.operatorId() << " - logging out";
|
|
if (m_logger.isDebugEnabled())
|
|
{
|
|
for (const auto &event : events)
|
|
DEBUG_LOG(m_logger) << "Alive history: " << event;
|
|
}
|
|
ObjectOperator *ifs = m_operatorObjMap.value(owa.operatorId());
|
|
it = m_aliveData.erase(it);
|
|
|
|
if (!ifs)
|
|
continue;
|
|
Database::OpmOperator op = ifs->data();
|
|
op.workstationIp = 0;
|
|
op.workstationId = QVariant();
|
|
m_mainHandler->getHandlerLockedTopics()->operatorLoggedOut(owa.operatorId()); // workstationId = 0 -> logout
|
|
m_mainHandler->getHandlerActiveApps()->cleanupOperator(owa.operatorId());
|
|
|
|
ifs->updateObject(op);
|
|
}
|
|
}
|
|
|
|
|
|
} // Namespace OperatorManagement
|