Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+156
@@ -0,0 +1,156 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
INCLUDE(MacroRTIDDSGen)
|
||||
INCLUDE(MacroCodeGenIdl)
|
||||
|
||||
SET(xml_FILE nom_service.xml)
|
||||
|
||||
#
|
||||
# --- Library svcNomCommon --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_common
|
||||
nom_export.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
# Generate nom_enums.idl / nom.idl
|
||||
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
|
||||
# Generate nom_db_impl.cpp/.h, nom_db.h
|
||||
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
|
||||
|
||||
# Generate *.cpp/*.hpp from idl
|
||||
RTIDDSGEN(SRCS_common nom_enums.idl)
|
||||
RTIDDSGEN(SRCS_common nom.idl)
|
||||
|
||||
# Generate nom_dt[s,c]_types.h, nom_ft[s,c]_types.h
|
||||
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
|
||||
# generate nom_[d|f]tc.h
|
||||
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS svcNomCommon SHARED ${SRCS_common})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcNomCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(svcNomCommon
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
ddscore
|
||||
ngldb
|
||||
LtsCommandLineParser
|
||||
NGLLogger
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcNomCommon)
|
||||
|
||||
#
|
||||
# --- Library svcNomClient --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_client
|
||||
nom_export.h
|
||||
)
|
||||
# generate nom_[d|f]tc_impl.[cpp|h]
|
||||
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS svcNomClient SHARED ${SRCS_client})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcNomClient
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcNomClient
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
PUBLIC
|
||||
svcNomCommon
|
||||
ddsftc
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcNomClient)
|
||||
|
||||
#
|
||||
# --- Library svcNomServer --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_server
|
||||
nom_export.h
|
||||
)
|
||||
# generate nom_[d|f]ts.h, nom_[d|f]ts_impl.[cpp|h]
|
||||
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV svcNomServer SHARED ${SRCS_server})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcNomServer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcNomServer
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
ddsfts
|
||||
PUBLIC
|
||||
svcNomCommon
|
||||
ngldb
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcNomServer)
|
||||
|
||||
#
|
||||
# --- Topic Type Plugin --------------------------------------------------------------
|
||||
#
|
||||
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
|
||||
|
||||
#
|
||||
# --- Executable svcNotificationManagement (sNOM) -------------------------------------------------
|
||||
#
|
||||
SET(SRCS_exe
|
||||
handler_notification.cpp
|
||||
handler_notification.h
|
||||
main.cpp
|
||||
main_handler.cpp
|
||||
main_handler.h
|
||||
object_notification.cpp
|
||||
object_notification.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
log4cxx_nom.props
|
||||
${xml_FILE}
|
||||
)
|
||||
|
||||
# Generate nom.sql, nom.xml
|
||||
CODEGEN_SQL(SRCS_exe ${xml_FILE})
|
||||
|
||||
NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
NGL_ADD_EXECUTABLE(AAR SV svcNotificationManagement ${SRCS_exe})
|
||||
NGL_TARGET_LINK_LIBRARIES(svcNotificationManagement
|
||||
Qt5::Core
|
||||
svcNomCommon
|
||||
svcNomServer
|
||||
svcExmClient
|
||||
svcOpmClient
|
||||
svcCoreClient
|
||||
ddsconnector
|
||||
nglsettings
|
||||
ProjectConfig
|
||||
NGLLogger
|
||||
nglcoreapplication
|
||||
ngltools
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcNotificationManagement)
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_nom.props DESTINATION bin)
|
||||
NGL_ADD_TARGET_LINK(svcNotificationManagement sNOM)
|
||||
|
||||
# Uncomment if necessary
|
||||
#ADD_SUBDIRECTORY(UnitTests)
|
||||
ADD_SUBDIRECTORY(ModuleTests)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(SRCS_MRK_TEST
|
||||
nom_tests.cpp
|
||||
nom_tests.h
|
||||
../settings.cpp
|
||||
../settings.h
|
||||
)
|
||||
|
||||
IF(BUILD_TESTING AND TARGET svcNomClient)
|
||||
# Testing FunctionTopic Functionality (FTC)
|
||||
ADD_EXECUTABLE(nomTests ${SRCS_MRK_TEST})
|
||||
TARGET_LINK_LIBRARIES(nomTests
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
RTI::nddscpp2
|
||||
svcNomClient
|
||||
svcOpmClient
|
||||
LtsCommandLineParser
|
||||
ddsconnector
|
||||
nglcoreapplication
|
||||
nglsettings
|
||||
ngltools
|
||||
)
|
||||
IF(NOT BUILD_RPM)
|
||||
NGL_INSTALL(AAR SV TARGETS nomTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_nom_module_tests.props DESTINATION bin/test)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: NotificationManagement
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.NOM=DEBUG
|
||||
#log4j.logger.NOM.main=DEBUG
|
||||
#log4j.logger.NOM.MainHandler=DEBUG
|
||||
#log4j.logger.NOM.DdsHandler=DEBUG
|
||||
#log4j.logger.NOM.DbHandler=DEBUG
|
||||
#log4j.logger.NOM.HandlerNotification=DEBUG
|
||||
#log4j.logger.NOM.ObjectNotification=DEBUG
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
log4j.appender.file=Lts::RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
@@ -0,0 +1,593 @@
|
||||
/**
|
||||
* MRK Function Topic test executable
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
#include "nom_tests.h"
|
||||
#include "ngltools/ngltools_filesystem.h"
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include <NotificationManagement/nom_ftc.h>
|
||||
#include <NotificationManagement/nom_dtc.h>
|
||||
#include <ParticipantManagement/ppm_operator_rights.h>
|
||||
#include <FileManagement/flm_operator_rights.h>
|
||||
#include <iostream>
|
||||
#include <NotificationManagement/settings.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <QSettings>
|
||||
|
||||
using namespace NotificationManagement;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NomTests::NomTests(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_exerciseId(0)
|
||||
, m_testId(0)
|
||||
, m_notificationId(0)
|
||||
, m_eTestStep(eUnknown)
|
||||
, m_bTestsSuccessful(true)
|
||||
, m_logger(getLogger("NomTests"))
|
||||
{
|
||||
qRegisterMetaType<Core::FunctionReply>("Core::FunctionReply");
|
||||
} // end of ctor()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NomTests::~NomTests()
|
||||
{
|
||||
} // end of dtor()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NomTests::init(int domainId, int exerciseId, int testId, int notificationId)
|
||||
{
|
||||
INFO_LOG(m_logger) << "MrkTests::init() "
|
||||
<< " domainId:" << domainId
|
||||
<< " exerciseId:" << exerciseId
|
||||
<< " testId: " << testId
|
||||
<< " notificationId: " << notificationId
|
||||
;
|
||||
|
||||
m_testId = testId;
|
||||
m_exerciseId = exerciseId;
|
||||
m_notificationId = notificationId;
|
||||
|
||||
// initialize DDS
|
||||
m_ddsConnector.reset(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::AllExercises, exerciseId));
|
||||
if (!m_ddsConnector->init())
|
||||
return false;
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
// Access to FTC
|
||||
TRACE_LOG(m_logger) << "create ftc";
|
||||
m_ftc = NotificationManagement::Interface::Ftc::create(m_ddsConnector);
|
||||
TRACE_LOG(m_logger) << "init ftc";
|
||||
bool bRet = m_ftc->enableAll();
|
||||
TRACE_LOG(m_logger) << "init end - bRet = " << bRet;
|
||||
|
||||
// Access to DTC
|
||||
TRACE_LOG(m_logger) << "create dtc";
|
||||
m_dtc = NotificationManagement::Interface::Dtc::create(m_ddsConnector);
|
||||
TRACE_LOG(m_logger) << "init dtc";
|
||||
bRet &= m_dtc->enableAll();
|
||||
TRACE_LOG(m_logger) << "init end - bRet = " << bRet;
|
||||
|
||||
|
||||
// Access to OPM DTC
|
||||
TRACE_LOG(m_logger) << "create opmDtc";
|
||||
m_opmDtc = OperatorManagement::Interface::Dtc::create(m_ddsConnector);
|
||||
m_opmDtc->enableUser();
|
||||
|
||||
return bRet;
|
||||
} // end of init()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::startTest()
|
||||
{
|
||||
INFO_LOG(m_logger) << "startTest() exerciseId:" << m_exerciseId
|
||||
<< " testId:" << m_testId
|
||||
<< " notificationId:" << m_notificationId
|
||||
;
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::nomNotificationChanged,
|
||||
this, &NomTests::onReceiveNotificationChanged);
|
||||
|
||||
switch(m_testId)
|
||||
{
|
||||
case 0:
|
||||
QTimer::singleShot(0, this, &NomTests::tryCreate);//command ./nomTests -d xx -e xx -t 0
|
||||
break;
|
||||
case 1:
|
||||
QTimer::singleShot(0, this, &NomTests::tryCreateHQ);//command ./nomTests -d xx -e xx -t 1
|
||||
break;
|
||||
case 2:
|
||||
QTimer::singleShot(0, this, &NomTests::tryReadReceipt);
|
||||
break;
|
||||
case 3:
|
||||
QTimer::singleShot(0, this, &NomTests::tryRemove);
|
||||
break;
|
||||
case 10:
|
||||
QTimer::singleShot(0, this, &NomTests::tryGetAllNotifications);
|
||||
break;
|
||||
case 11:
|
||||
QTimer::singleShot(0, this, &NomTests::tryGetNotification);
|
||||
break;
|
||||
}
|
||||
|
||||
} // end of startTest()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::tryCreate()
|
||||
{
|
||||
m_eTestStep = eCreate;
|
||||
CreateNotificationRequest data;
|
||||
getCreateNotificationRequestData(data);
|
||||
|
||||
INFO_LOG(m_logger) << "trying to send CreateNotificationRequest";
|
||||
if (!m_ftc->createNotificationRequest(data, this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting create data";
|
||||
failExit();
|
||||
}
|
||||
}
|
||||
|
||||
void NomTests::tryCreateHQ()
|
||||
{
|
||||
|
||||
QScopedPointer<NGL::Settings> s (new NGL::Settings(NGL::findProjectConfigFile()));
|
||||
qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
|
||||
qint64 expiryTime = currentTime + Settings::expiryIntervalMSec();
|
||||
NotificationManagement::NomNotification notif;
|
||||
|
||||
notif.title(tr("HQ Reports ").toStdString());
|
||||
|
||||
// format: "[Open HQ Report Dialog](//flmHQReport/party=3&folder=51&file=12)"
|
||||
// Open HQ Report Dialog : this text link will display on notification and is clickable
|
||||
// url().host() to get host scheme_identifier: flmHQReport
|
||||
// QString data = url().path().mid(1) to get "party=3&folder=51&file=12".
|
||||
// with QUrlQuery query(data); // get each parameter: query.queryItemValue("party").toInt(); // same for the others
|
||||
/// retrieve data in flm_explorer_gui_plugin.cpp
|
||||
|
||||
int partyId = 3; // place holder from ex_42.pppm_party PartyId BLUE
|
||||
int folderId = 51; // place holder from flm_folder
|
||||
int fileId = 12; // place holder from flm_file_content
|
||||
QString linkName = QStringLiteral("Open HQ Report Dialog");
|
||||
QString content = QStringLiteral("[%1](//flmHQReport/?party=%2&folder=%3&file=%4)");
|
||||
content = content.arg(linkName).arg(partyId).arg(folderId).arg(fileId);
|
||||
notif.content(content.toStdString());
|
||||
notif.timeStamp(currentTime);
|
||||
notif.expiryTime(expiryTime);
|
||||
|
||||
notif.priority(static_cast<NotificationManagement::Priority_def::type>(Settings::notificationPriority()));
|
||||
notif.processedPriority(NotificationManagement::Priority_def::Highest);
|
||||
notif.exerciseId(m_exerciseId);
|
||||
|
||||
for (const auto &userId : m_opmDtc->getOperatorsByOperatorRight(OperatorRights::FileManagementFilesEdit))
|
||||
{
|
||||
NotificationManagement::Address addr;
|
||||
addr.addressId(userId);
|
||||
addr.isRead(false);
|
||||
QString name = QStringLiteral("Operator ") + QString::number(userId);
|
||||
addr.name(name.toStdString());
|
||||
addr.addressType(NotificationManagement::AddressType_def::Operator);
|
||||
addr.addressSubId(userId+10);
|
||||
notif.recipientIds().push_back(addr);
|
||||
}
|
||||
|
||||
// NotificationManagement::Address addrSender;
|
||||
// addrSender.addressId(FileManagement::Offset);
|
||||
// addrSender.name(tr("[FileManagement2](flmHQReport)").toStdString());
|
||||
// addrSender.addressType(NotificationManagement::AddressType_def::Service);
|
||||
// addrSender.addressSubId(321);
|
||||
// notif.sender(addrSender);
|
||||
|
||||
NotificationManagement::CreateNotificationRequest notifReq;
|
||||
notifReq.notification(notif);
|
||||
|
||||
if (!m_ftc->createNotificationRequest(notifReq, this))
|
||||
ERROR_LOG(m_logger) << "Error requesting create Notification data";
|
||||
|
||||
} // end of tryCreate()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::tryReadReceipt()
|
||||
{
|
||||
m_eTestStep = eReadReceipt;
|
||||
|
||||
m_dtc->waitForHistoricalDataNomNotification();
|
||||
NotificationManagement::NomNotification data = m_dtc->nomNotification(m_notificationId);
|
||||
|
||||
NotificationManagement::Address recipientAddress = data.recipientIds().front();
|
||||
//NotificationManagement::Address recipientAddress = data.recipientIds().at(2);
|
||||
NotificationManagement::ReadReceiptRequest request;
|
||||
request.addressId(recipientAddress.id());
|
||||
request.operatorId(recipientAddress.addressId());
|
||||
request.workstationId(0);
|
||||
|
||||
request.notificationIds({m_notificationId});
|
||||
request.processed(true);
|
||||
|
||||
INFO_LOG(m_logger) << "trying to send CreateNotificationRequest";
|
||||
if (!m_ftc->readReceiptRequest(request, this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting readReceipt data";
|
||||
failExit();
|
||||
}
|
||||
} // end of tryReadReceipt
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::tryRemove()
|
||||
{
|
||||
m_eTestStep = eRemove;
|
||||
/*
|
||||
NotificationRemoveRequest data;
|
||||
|
||||
data.id(m_notificationId);
|
||||
|
||||
INFO_LOG(m_logger) << "trying to send remove request for notificationId:" << data.id();
|
||||
if (!m_ftc->notificationRemoveRequest(data, this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting remove data for notificationId:" << data.id();
|
||||
failExit();
|
||||
}
|
||||
*/
|
||||
|
||||
} // end of tryRemove()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::tryGetAllNotifications()
|
||||
{
|
||||
m_eTestStep = eGetAllNotifications;
|
||||
DEBUG_LOG(m_logger) << "trying to get all notifications";
|
||||
|
||||
m_dtc->waitForHistoricalDataNomNotification();
|
||||
if (m_dtc->nomNotifications().isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting all notification data";
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const NomNotification ¬if : m_dtc->nomNotifications())
|
||||
{
|
||||
// needed for Test 11 tryGetNotification
|
||||
m_notificationId = notif.id();
|
||||
|
||||
INFO_LOG(m_logger) << "Nom(" << notif.id() << ") :"
|
||||
<< " title:" << notif.title()
|
||||
<< " content:" << notif.content()
|
||||
<< " timeStamp:" << notif.timeStamp()
|
||||
<< " priority:" << notif.priority()
|
||||
<< " processed: " << notif.processed()
|
||||
<< " processedTime: " << notif.processTime()
|
||||
<< " processPrio: " << notif.processedPriority()
|
||||
<< " recipient count:" << notif.recipientIds().size();
|
||||
|
||||
INFO_LOG(m_logger) << "SenderAddress(" << notif.sender().id() << ") :"
|
||||
<< " name: " << notif.sender().name()
|
||||
<< ", addressId: " << notif.sender().addressId()
|
||||
<< ", addressSubId: " << notif.sender().addressSubId()
|
||||
<< ", addressSubSubId: " << notif.sender().addressSubSubId()
|
||||
<< ", addressType: " << notif.sender().addressType();
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
|
||||
} // end of tryGetAllNotifications()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::tryGetNotification()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "trying to get notification with id:" << m_notificationId;
|
||||
|
||||
if (m_testId > 1)
|
||||
m_eTestStep = eGetNotification;
|
||||
|
||||
if (m_notificationId <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "invalid notificationId - test aborted.";
|
||||
failExit();
|
||||
}
|
||||
|
||||
m_dtc->waitForHistoricalDataNomNotification();
|
||||
NotificationManagement::NomNotification notif = m_dtc->nomNotification(m_notificationId);
|
||||
|
||||
if (notif.id() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error receiving data for notificationId " << m_notificationId << " returnVal:" << notif.id();
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(m_logger) << "NomNotification(" << notif.id() << ") :"
|
||||
<< " title:" << notif.title()
|
||||
<< " content:" << notif.content()
|
||||
<< " timeStamp:" << notif.timeStamp()
|
||||
<< " priority:" << notif.priority()
|
||||
<< " processed: " << notif.processed()
|
||||
<< " processedTime: " << notif.processTime()
|
||||
<< " processPrio: " << notif.processedPriority()
|
||||
<< " recipient count:" << notif.recipientIds().size();
|
||||
|
||||
for (const NotificationManagement::Address &addr : notif.recipientIds())
|
||||
{
|
||||
INFO_LOG(m_logger) << "Recipient(" << addr.id() << ") :"
|
||||
<< " name: " << addr.name()
|
||||
<< ", addressId: " << addr.addressId()
|
||||
<< ", addressSubId: " << addr.addressSubId()
|
||||
<< ", addressSubSubId: " << addr.addressSubSubId()
|
||||
<< ", addressType: " << addr.addressType()
|
||||
<< ", isRead: " << addr.isRead();
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "SenderAddress(" << notif.sender().id() << ") :"
|
||||
<< " name: " << notif.sender().name()
|
||||
<< ", addressId: " << notif.sender().addressId()
|
||||
<< ", addressSubId: " << notif.sender().addressSubId()
|
||||
<< ", addressSubSubId: " << notif.sender().addressSubSubId()
|
||||
<< ", addressType: " << notif.sender().addressType();
|
||||
}
|
||||
|
||||
if (m_testId == 0)
|
||||
{
|
||||
if (m_eTestStep == eCreate)
|
||||
{
|
||||
if (! onCompareCreatedData(notif))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Compare created data failed!";
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
QTimer::singleShot(0, this, &NomTests::tryReadReceipt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
|
||||
} // end of tryGetNotification()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::onCreateNotificationReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got createReply with id " << replyObject.id()
|
||||
<< " and errorString " << replyObject.translated();
|
||||
|
||||
m_notificationId = replyObject.id();
|
||||
|
||||
if (replyObject.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting create data";
|
||||
failExit();
|
||||
return;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "Requesting create data ok. Got new id:" << replyObject.id() << " ... ok.";
|
||||
|
||||
if (m_testId == 0)
|
||||
// QTimer::singleShot(0, this, &NomTests::tryModify()));
|
||||
QTimer::singleShot(0, this, &NomTests::tryGetNotification);
|
||||
else
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
|
||||
} // end of onNotificationCreateReply()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::onReadReceiptReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
|
||||
INFO_LOG(m_logger) << "Got onReadReceipt with id " << replyObject.id()
|
||||
<< " and errorString " << replyObject.translated();
|
||||
|
||||
if (replyObject.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting ReadReceipt data for id:" << replyObject.id();
|
||||
failExit();
|
||||
return;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "Requesting ReadReceipt data for id:" << replyObject.id() << " ... ok.";
|
||||
|
||||
if (m_testId == 0)
|
||||
// QTimer::singleShot(0, this, &MrkTests::tryDelete()));
|
||||
QTimer::singleShot(0, this, &NomTests::tryGetNotification);
|
||||
else
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
|
||||
} // end of onReadReceiptReply()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
void NomTests::onNotificationRemoveReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got removeReply with id " << replyObject.id()
|
||||
<< " and errorString " << replyObject.translated();
|
||||
|
||||
if (replyObject.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting remove data for NotificationId:" << replyObject.id();
|
||||
failExit();
|
||||
return;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "Requesting remove data for NotificationId:" << replyObject.id() << " ... ok.";
|
||||
|
||||
if (m_testId == 0)
|
||||
{
|
||||
QTimer::singleShot(0, this, &MrkTests::tryCreateSnapshot);
|
||||
// ansonsten verheriger Ausstieg mit Errorlog.
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
|
||||
} // end of onNotificationRemoveReply()
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::onReceiveNotificationChanged(const NomNotification &data, DataModification modType)
|
||||
{
|
||||
// INFO_LOG(m_logger) << "onReceiveNotificationChanged() notificationId:" << data.id()
|
||||
// << " modificationType: = " << (int)modType<< " received";
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
INFO_LOG(m_logger) << "*** NomNotification added received. notificationId:" << data.id();
|
||||
break;
|
||||
|
||||
case DataModification::eModified:
|
||||
INFO_LOG(m_logger) << "*** NomNotification modified received. notificationId:" << data.id();
|
||||
break;
|
||||
|
||||
case DataModification::eRemoved:
|
||||
INFO_LOG(m_logger) << "*** NomNotification removed received. notificationId:" << data.id();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} // end of onReceiveNotificationChanged()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::getCreateNotificationRequestData(CreateNotificationRequest &data)
|
||||
{
|
||||
qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
// 100 seconds
|
||||
qint64 expiryTime = currentTime + 100 * 1000;
|
||||
NotificationManagement::NomNotification notif;
|
||||
|
||||
notif.title("TestNotificationCreate");
|
||||
notif.content("Dies ist ein Test mit Content");
|
||||
notif.timeStamp(currentTime);
|
||||
notif.expiryTime(expiryTime);
|
||||
notif.priority(NotificationManagement::Priority_def::High);
|
||||
notif.processedPriority(NotificationManagement::Priority_def::Low);
|
||||
notif.exerciseId(m_exerciseId);
|
||||
|
||||
for (int i=10; i< 24; i++)
|
||||
{
|
||||
NotificationManagement::Address addr;
|
||||
addr.addressId(i);
|
||||
addr.isRead(false);
|
||||
QString name = QStringLiteral("Operator ") + QString::number(i);
|
||||
addr.name(name.toStdString());
|
||||
addr.addressType(NotificationManagement::AddressType_def::Operator);
|
||||
addr.addressSubId(i+10);
|
||||
notif.recipientIds().push_back(addr);
|
||||
}
|
||||
|
||||
NotificationManagement::Address wsAddr;
|
||||
wsAddr.addressId(302);
|
||||
wsAddr.isRead(false);
|
||||
QString name = QStringLiteral("Workstation 2 ");
|
||||
wsAddr.name(name.toStdString());
|
||||
wsAddr.addressType(NotificationManagement::AddressType_def::Workstation);
|
||||
notif.recipientIds().push_back(wsAddr);
|
||||
|
||||
NotificationManagement::Address addrSender;
|
||||
addrSender.addressId(ParticipantManagement::Offset);
|
||||
addrSender.name(QStringLiteral("svcParticipantManagement ").toStdString());
|
||||
addrSender.addressType(NotificationManagement::AddressType_def::Service);
|
||||
notif.sender(addrSender);
|
||||
|
||||
data.notification(notif);
|
||||
} // end of getCreateNotificationRequestData()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool NomTests::onCompareCreatedData(NomNotification &data)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "start onCompareCreatedData() for id :" << data.id();
|
||||
|
||||
// Vergleicht die zurueckgelesen Datan mit den statischen create Daten
|
||||
|
||||
CreateNotificationRequest createData;
|
||||
|
||||
getCreateNotificationRequestData(createData);
|
||||
|
||||
if (createData.notification().title() != data.title())
|
||||
return false;
|
||||
|
||||
if (createData.notification().priority() != data.priority())
|
||||
return false;
|
||||
if (createData.notification().content() != data.content())
|
||||
return false;
|
||||
if (createData.notification().processedPriority() != data.processedPriority())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} // end of onCompareCreatedData()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void NomTests::failExit()
|
||||
{
|
||||
m_bTestsSuccessful = false;
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser()
|
||||
: LtsCommandLineParser()
|
||||
{
|
||||
addOption({ QStringList() << QStringLiteral("t") << QStringLiteral("testId")
|
||||
, QStringLiteral("TestId.")
|
||||
, QStringLiteral("Default: 0 (all FTC/DTC tests), 1 create, 2 readReceipt, 3 remove, 10 getAllNotification and Recipients, 11 getNotification")
|
||||
, QStringLiteral("0")
|
||||
});
|
||||
|
||||
addOption({ QStringList() << QStringLiteral("n") << QStringLiteral("notificationId")
|
||||
, QStringLiteral("NotificationId.")
|
||||
, QStringLiteral("Used for tests 2, 3 & 11 only to select the notification")
|
||||
, QStringLiteral("0")
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
int testId() const { return isSet(QStringLiteral("t")) ? value(QStringLiteral("t")).toInt() : -1; }
|
||||
int notificationId() const { return isSet(QStringLiteral("n")) ? value(QStringLiteral("n")).toInt() : -1; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("nom", "log4cxx_nom_module_tests.props");
|
||||
|
||||
int iRet = -1;
|
||||
CmdLineParser options;
|
||||
if (!options.init())
|
||||
return iRet;
|
||||
|
||||
std::unique_ptr<NotificationManagement::NomTests> NomTests(new NotificationManagement::NomTests);
|
||||
if (!NomTests->init(options.domainId(), options.exerciseId(), options.testId(), options.notificationId()))
|
||||
return iRet;
|
||||
|
||||
QTimer::singleShot(2000, NomTests.get(), &NotificationManagement::NomTests::startTest);
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
app.exec();
|
||||
|
||||
iRet = NomTests->testsSuccessful() ? 0 : 1;
|
||||
fprintf(stderr, "%d\n", iRet);
|
||||
|
||||
DEBUG_LOG(app.baseLogger()) << "** TEST result = " << iRet;
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
|
||||
return iRet;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
*
|
||||
* EXM Function Topic test executable
|
||||
*
|
||||
* ModuleTests for createNotification/readReceipt
|
||||
* ---------------------------------------------------
|
||||
* Client FTC is implemented
|
||||
*
|
||||
* => (!) Preconditon:
|
||||
* - Service svcNotificationManagent running
|
||||
*
|
||||
* -------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <NotificationManagement/nom_ftc.h>
|
||||
#include <NotificationManagement/nom_ftc_types.h>
|
||||
#include <NotificationManagement/nom_dtc.h>
|
||||
#include <NotificationManagement/nom_dtc_types.h>
|
||||
#include <NotificationManagement/logger.h>
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
class NomTests : public QObject
|
||||
, protected NotificationManagement::Interface::Ftc::CreateNotificationReplyHandler
|
||||
, protected NotificationManagement::Interface::Ftc::ReadReceiptReplyHandler
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NomTests(QObject *parent = nullptr);
|
||||
~NomTests();
|
||||
|
||||
bool init(int domainId, int exerciseId, int testId, int notificationId);
|
||||
bool testsSuccessful() const { return m_bTestsSuccessful; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void startTest();
|
||||
|
||||
protected Q_SLOTS:
|
||||
// used to check FTC
|
||||
void tryCreate();
|
||||
void tryCreateHQ();
|
||||
void tryReadReceipt();
|
||||
void tryRemove();
|
||||
|
||||
|
||||
// used to check DTC
|
||||
void tryGetAllNotifications();
|
||||
void tryGetNotification();
|
||||
|
||||
// used to check DTC signal/slot connection
|
||||
void onReceiveNotificationChanged(const NomNotification &data, DataModification modType);
|
||||
|
||||
protected:
|
||||
// Callbackfunctions for FTC
|
||||
void onCreateNotificationReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onReadReceiptReply(const Core::FunctionReplyObject &reply) override final;
|
||||
|
||||
private Q_SLOTS:
|
||||
bool onCompareCreatedData(NomNotification &data);
|
||||
//bool onCompareModifiedData(NomNotification &data);
|
||||
|
||||
private:
|
||||
void getCreateNotificationRequestData(CreateNotificationRequest &data);
|
||||
void failExit();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<NotificationManagement::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<NotificationManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
|
||||
|
||||
qint32 m_exerciseId;
|
||||
int m_testId;
|
||||
int m_notificationId;
|
||||
|
||||
enum TestStep
|
||||
{
|
||||
eUnknown,
|
||||
eCreate,
|
||||
eReadReceipt,
|
||||
eRemove,
|
||||
eGetAllNotifications,
|
||||
eGetNotification
|
||||
} m_eTestStep;
|
||||
|
||||
bool m_bTestsSuccessful;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // namespace NotificationManagement
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-02
|
||||
*/
|
||||
|
||||
#include "dds_handler.h"
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
DdsHandler::DdsHandler(int domainId)
|
||||
: m_ddsConnector(std::make_shared<DDSConnector::DdsConnector>(domainId, IDL::PartitionType::AllExercises))
|
||||
, m_logger(getLogger("DdsHandler"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DdsHandler(" << domainId << ") for partition: " << m_ddsConnector->getDefaultPartition();
|
||||
} // end of ctor()DdsHandler
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DdsHandler::init(const QStringList &qosFileList)
|
||||
{
|
||||
if (!m_ddsConnector->init(qosFileList))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
|
||||
return false;
|
||||
}
|
||||
|
||||
// default initialize Publisher and Subscriber
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
// Pacemaker
|
||||
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
|
||||
|
||||
// DTC Core (to get partitionTime)
|
||||
m_dtcCore = Core::Interface::Dtc::create(m_ddsConnector);
|
||||
m_dtcCore->enablePartitionTime();
|
||||
|
||||
// DTS
|
||||
m_ddsDts = NotificationManagement::Interface::Dts::create(m_ddsConnector);
|
||||
bool bRet = m_ddsDts->enableAll();
|
||||
INFO_LOG(m_logger) << "Dts initialised";
|
||||
|
||||
// FTS
|
||||
m_ddsFts = NotificationManagement::Interface::Fts::create(m_ddsConnector);
|
||||
bRet &= m_ddsFts->enableAll();
|
||||
INFO_LOG(m_logger) << "Fts initialised";
|
||||
|
||||
// DtcExm
|
||||
m_dtcExm = ExerciseManagement::Interface::Dtc::create(m_ddsConnector);
|
||||
bRet &= m_dtcExm->enableExercise();
|
||||
INFO_LOG(m_logger) << "DtcExm initialised";
|
||||
|
||||
// DtcOpm
|
||||
m_dtcOpm = OperatorManagement::Interface::Dtc::create(m_ddsConnector);
|
||||
bRet &= m_dtcOpm->enableUser();
|
||||
INFO_LOG(m_logger) << "DtcOpm initialised";
|
||||
|
||||
return bRet;
|
||||
} // end of init()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
qint64 DdsHandler::currentPartitionTime() const { return m_dtcCore->partitionTime().timeStamp(); }
|
||||
|
||||
} // Namespace NotificationManagement
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-02
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <DDS/Core/core_dtc.h>
|
||||
#include <DDS/Core/topic_lock_master.h>
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <NotificationManagement/nom_dts.h>
|
||||
#include <NotificationManagement/nom_fts.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
class DdsHandler final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DdsHandler(int domainId);
|
||||
|
||||
bool init(const QStringList &qosFileList = QStringList());
|
||||
bool enableEquipmentMessage();
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsConnector() const { return m_ddsConnector; }
|
||||
std::shared_ptr<Core::Pacemaker> pacemaker() const { return m_pacemaker; }
|
||||
std::shared_ptr<Core::TopicLockMaster> topicLockMaster() const { return m_topicLockMaster; }
|
||||
std::shared_ptr<NotificationManagement::Interface::Dts> dts() const { return m_ddsDts; }
|
||||
std::shared_ptr<NotificationManagement::Interface::Fts> fts() const { return m_ddsFts; }
|
||||
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> dtcExm() const { return m_dtcExm; } ///< Pointer to DTC ExerciseManagement interface object
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> dtcOpm() const { return m_dtcOpm; } ///< Pointer to DTC OperatorManagement interface object
|
||||
|
||||
qint64 currentPartitionTime() const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<Core::Interface::Dtc> m_dtcCore;
|
||||
std::shared_ptr<Core::Pacemaker> m_pacemaker;
|
||||
std::shared_ptr<Core::TopicLockMaster> m_topicLockMaster;
|
||||
std::shared_ptr<NotificationManagement::Interface::Dts> m_ddsDts;
|
||||
std::shared_ptr<NotificationManagement::Interface::Fts> m_ddsFts;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_dtcExm;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtcOpm;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
* 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 ¬if)
|
||||
{
|
||||
// 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
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Handler for all notifcation objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include <NotificationManagement/nom_db.h>
|
||||
#include <QTimer>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
// Forwarddeclarations
|
||||
class DdsHandler;
|
||||
class ObjectNotification;
|
||||
|
||||
class HandlerNotification final : public QObject
|
||||
, protected Interface::Fts::CreateNotificationRequestHandler
|
||||
, protected Interface::Fts::ReadReceiptRequestHandler
|
||||
, protected Interface::Fts::DeleteMessageRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HandlerNotification(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db);
|
||||
|
||||
~HandlerNotification();
|
||||
|
||||
bool init();
|
||||
|
||||
private: // methods
|
||||
void onCreateNotificationRequest(const rti::core::SampleIdentity &cookie,
|
||||
const CreateNotification &request) override final;
|
||||
void onReadReceiptRequest(const rti::core::SampleIdentity &cookie,
|
||||
const ReadReceipt &request) override final;
|
||||
void onDeleteMessageRequest(const rti::core::SampleIdentity &cookie,
|
||||
const DeleteMessage &request) override final;
|
||||
|
||||
bool isRemoveable(const NomNotification ¬if);
|
||||
|
||||
private slots:
|
||||
void onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType);
|
||||
void onCheckRemove();
|
||||
|
||||
private: // attributes
|
||||
QTimer* m_removeNotificationTimer;
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<DatabaseInterface> m_db;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
QHash<int, ObjectNotification *> m_objectNotificationMap; // Key = notificationId
|
||||
};
|
||||
|
||||
|
||||
} // namespace NotificationManagement
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: NotificationManagement
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.NOM=DEBUG
|
||||
#log4j.logger.NOM.main=DEBUG
|
||||
#log4j.logger.NOM.MainHandler=DEBUG
|
||||
#log4j.logger.NOM.DdsHandler=DEBUG
|
||||
#log4j.logger.NOM.DbHandler=DEBUG
|
||||
#log4j.logger.NOM.HandlerNotification=DEBUG
|
||||
#log4j.logger.NOM.ObjectNotification=DEBUG
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
log4j.appender.file=Lts::RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "NOM.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NotificationManagement
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "nom_export.h"
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
NOM_COMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace NotificationManagement
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* main for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "logger.h"
|
||||
#include "settings.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
app.createLogger("NOM", options.exerciseId());
|
||||
|
||||
NotificationManagement::Settings::setIniFile(options.iniFile());
|
||||
|
||||
int iRet = -3;
|
||||
{
|
||||
std::unique_ptr<NotificationManagement::MainHandler> mainHandler(new NotificationManagement::MainHandler);
|
||||
|
||||
if (!mainHandler->init(options.domainId()))
|
||||
return iRet;
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
iRet = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* MainHandler for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
#include <ngldb/db_service_handler.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
MainHandler::MainHandler()
|
||||
: m_logger(getLogger("MainHandler"))
|
||||
{
|
||||
INFO_LOG(m_logger) << "MainHandler::MainHandler";
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
INFO_LOG(m_logger) << "MainHandler::~MainHandler";
|
||||
m_ddsHandler = nullptr;
|
||||
m_dbHandler = nullptr;
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool MainHandler::init(int domainId)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Start MessageDataManagement MainHandler. domainId ="<<domainId;
|
||||
|
||||
// initialize DDS
|
||||
m_ddsHandler = std::make_shared<DdsHandler>(domainId);
|
||||
if (!m_ddsHandler->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation DdsHandler failed.";
|
||||
if (m_ddsHandler->pacemaker())
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << "m_ddsHandler initialized. ";
|
||||
|
||||
// initialize database
|
||||
m_dbHandler = std::make_shared<DbHandler>();
|
||||
if (!m_dbHandler->init(0, Settings::settings()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation DbHandler failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << "DbHandler initialized. ";
|
||||
|
||||
INFO_LOG(m_logger) << "create HandlerNotification. ";
|
||||
m_handlerNotification = std::make_shared<HandlerNotification>(m_ddsHandler, m_dbHandler->db());
|
||||
if (!m_handlerNotification->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "create HandlerNotification failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << "HandlerNotification initialized";
|
||||
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
|
||||
//m_ddsHandler->enableEquipmentMessage();
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
} // namespace NotificationManagement
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* MainHandler for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-09-21
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "handler_notification.h"
|
||||
#include <NotificationManagement/nom_db.h>
|
||||
#include "logger.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace NGLDB
|
||||
{
|
||||
template <typename DB> class DbServiceHandler;
|
||||
}
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
|
||||
class MainHandler final
|
||||
{
|
||||
public:
|
||||
MainHandler();
|
||||
~MainHandler();
|
||||
|
||||
bool init(int domainId);
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler; ///< Pointer to DDS handler
|
||||
std::shared_ptr<DbHandler> m_dbHandler; ///< Pointer to DB handler
|
||||
std::shared_ptr<HandlerNotification> m_handlerNotification;
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
} // namespace NotificationManagement
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Export definitions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-08-04
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef NOM_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define NOM_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCNOMCOMMON_LIB)
|
||||
# define NOM_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define NOM_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NOM_CLIENT_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define NOM_CLIENT_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCNOMCLIENT_LIB)
|
||||
# define NOM_CLIENT_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define NOM_CLIENT_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NOM_SERVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define NOM_SERVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCNOMSERVER_LIB)
|
||||
# define NOM_SERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define NOM_SERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="NotificationManagement" abbreviation="NOM" procNames="NotificationManagement" exerciseDependency="Global" groups="Core">
|
||||
<rcs>
|
||||
<Id Id="$Id: ea_export_script.txt 51656 2020-07-13 08:38:27Z diers $"/>
|
||||
<HeadURL HeadURL="$HeadURL: svn://192.168.133.21/TDS/branches/product/devel/trunk/Lts/Common/CodeGen/ea_export_script.txt $"/>
|
||||
<Author Author="$Author: diers $"/>
|
||||
</rcs>
|
||||
<tables>
|
||||
<table name="address_type">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="name" datatype="text"/>
|
||||
</table>
|
||||
<table name="nom_address">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="address_type_id" datatype="integer" isForeignKey="1"/>
|
||||
<column name="address_id" datatype="integer"/>
|
||||
<column name="name" datatype="text"/>
|
||||
<column name="address_sub_id" datatype="integer"/>
|
||||
<column name="address_sub_sub_id" datatype="integer"/>
|
||||
<column name="is_read" datatype="boolean"/>
|
||||
<column name="notification_id" datatype="integer" isForeignKey="1"/>
|
||||
<column name="is_sender" datatype="boolean"/>
|
||||
<column name="is_deleted" datatype="boolean"/>
|
||||
<foreignKey name="FK_nom_address_nom_notification">
|
||||
<source table="nom_address" column="notification_id"/>
|
||||
<destination table="nom_notification" column="id"/>
|
||||
</foreignKey>
|
||||
<foreignKey name="FK_nom_address_address_type">
|
||||
<source table="nom_address" column="address_type_id"/>
|
||||
<destination table="address_type" column="id"/>
|
||||
</foreignKey>
|
||||
</table>
|
||||
<table name="nom_notification">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="content" datatype="text"/>
|
||||
<column name="exercise_id" datatype="integer"/>
|
||||
<column name="expiry_time" datatype="bigint"/>
|
||||
<column name="priority_id" datatype="integer" isForeignKey="1"/>
|
||||
<column name="processed" datatype="integer"/>
|
||||
<column name="processed_priority" datatype="integer" isForeignKey="1"/>
|
||||
<column name="process_time" datatype="bigint"/>
|
||||
<column name="time_stamp" datatype="bigint"/>
|
||||
<column name="title" datatype="text"/>
|
||||
<column name="message_type" datatype="integer"/>
|
||||
<column name="notification_type" datatype="integer"/>
|
||||
<column name="properties" datatype="jsonb"/>
|
||||
<foreignKey name="FK_nom_notification_priority_prio">
|
||||
<source table="nom_notification" column="priority_id"/>
|
||||
<destination table="priority" column="id"/>
|
||||
</foreignKey>
|
||||
<foreignKey name="FK_nom_notification_priority_processed">
|
||||
<source table="nom_notification" column="processed_priority"/>
|
||||
<destination table="priority" column="id"/>
|
||||
</foreignKey>
|
||||
</table>
|
||||
<table name="priority">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="name" datatype="text"/>
|
||||
</table>
|
||||
</tables>
|
||||
<views/>
|
||||
<dbServiceStructs>
|
||||
<serviceStruct name="NomAddress" table="nom_address"/>
|
||||
<serviceStruct name="NomNotification" table="nom_notification"/>
|
||||
<table name="nom_address"/>
|
||||
<table name="nom_notification"/>
|
||||
</dbServiceStructs>
|
||||
<topicTypes>
|
||||
<topicType name="Address">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="addressType" idlType="AddressType"/>
|
||||
<column name="addressId" idlType="long"/>
|
||||
<column name="name" idlType="string"/>
|
||||
<column name="addressSubId" idlType="long"/>
|
||||
<column name="addressSubSubId" idlType="long"/>
|
||||
<column name="isRead" idlType="boolean"/>
|
||||
<column name="isDeleted" idlType="boolean"/>
|
||||
</topicType>
|
||||
<topicType name="CreateNotification">
|
||||
<column name="notification" idlType="NomNotification"/>
|
||||
</topicType>
|
||||
<topicType name="NomNotification" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0">
|
||||
<column name="content" idlType="string"/>
|
||||
<column name="contentArgs" idlType="sequence<string>"/>
|
||||
<column name="exerciseId" idlType="long" comment="When the exercise is deleted, all notifications have to be deleted as well..."/>
|
||||
<column name="expiryTime" idlType="long long" comment="after expiration, the priority is always Low, no matter what priority says. 0 for never."/>
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="priority" idlType="Priority"/>
|
||||
<column name="processed" idlType="long" comment="address.id of the receipient who processed the notification"/>
|
||||
<column name="processedPriority" idlType="Priority" comment="new Priority, this notification shall have for all other receipients, after the notification has been processed by one receipient (when erosion has taken place)."/>
|
||||
<column name="processTime" idlType="long long"/>
|
||||
<column name="recipientIds" idlType="sequence<Address>"/>
|
||||
<column name="sender" idlType="Address"/>
|
||||
<column name="timeStamp" idlType="long long"/>
|
||||
<column name="title" idlType="string"/>
|
||||
<column name="titleArgs" idlType="sequence<string>"/>
|
||||
<column name="messageType" idlType="MessageType"/>
|
||||
<column name="notificationType" idlType="NotificationType"/>
|
||||
</topicType>
|
||||
<topicType name="ReadReceipt">
|
||||
<column name="addressId" idlType="long" comment="address.id of the receipient who read/processed the notificaton"/>
|
||||
<column name="operatorId" idlType="long"/>
|
||||
<column name="workstationId" idlType="long"/>
|
||||
<column name="notificationIds" idlType="sequence<long>"/>
|
||||
<column name="processed" idlType="boolean" comment="check, if the not only the notification has been read, but the task given was also processed."/>
|
||||
</topicType>
|
||||
<topicType name="DeleteMessage">
|
||||
<column name="addressId" idlType="long" comment="address.id of the receipient who read/processed the notificaton"/>
|
||||
<column name="operatorId" idlType="long"/>
|
||||
<column name="workstationId" idlType="long"/>
|
||||
<column name="notificationIds" idlType="sequence<long>"/>
|
||||
</topicType>
|
||||
</topicTypes>
|
||||
<functionTopics>
|
||||
<functionTopic name="CreateNotification" requestTopicType="CreateNotification" replyTopicType="Core::FunctionReply" requestTopicName="CreateNotificationRequest" replyTopicName="CreateNotificationReply" routeInReplay="0"/>
|
||||
<functionTopic name="ReadReceipt" requestTopicType="ReadReceipt" replyTopicType="Core::FunctionReply" requestTopicName="ReadReceiptRequest" replyTopicName="ReadReceiptReply" routeInReplay="0"/>
|
||||
<functionTopic name="DeleteMessage" requestTopicType="DeleteMessage" replyTopicType="Core::FunctionReply" requestTopicName="DeleteMessageRequest" replyTopicName="DeleteMessageReply" routeInReplay="0"/>
|
||||
</functionTopics>
|
||||
<enumerations>
|
||||
<enumeration name="Priority" table="priority">
|
||||
<attribute key="Highest" value="1"/>
|
||||
<attribute key="High" value="2"/>
|
||||
<attribute key="Normal" value="3"/>
|
||||
<attribute key="Low" value="4"/>
|
||||
</enumeration>
|
||||
<enumeration name="AddressType" table="address_type">
|
||||
<attribute key="Service" value="0"/>
|
||||
<attribute key="Operator" value="1"/>
|
||||
<attribute key="Workstation" value="2"/>
|
||||
<attribute key="Participant" value="3"/>
|
||||
</enumeration>
|
||||
<enumeration name="NotificationType">
|
||||
<attribute key="AdlerNotification" value="0"/>
|
||||
<attribute key="CombatOrder" value="1"/>
|
||||
</enumeration>
|
||||
<enumeration name="MessageType">
|
||||
<attribute key="Success" value="0"/>
|
||||
<attribute key="Error" value="1"/>
|
||||
<attribute key="Warning" value="2"/>
|
||||
<attribute key="Info" value="3"/>
|
||||
</enumeration>
|
||||
</enumerations>
|
||||
<operatorRights offset="54"/>
|
||||
</service>
|
||||
+427
@@ -0,0 +1,427 @@
|
||||
/**
|
||||
* NomNotification object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
|
||||
#include "object_notification.h"
|
||||
#include "dds_handler.h"
|
||||
#include <ngldb/dbtransaction.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
const QString TRANSLATION_ARGS = QStringLiteral("translationsArgs");
|
||||
const QString CONTENT_ID = QStringLiteral("id");
|
||||
const QString CONTENT_ARG = QStringLiteral("contentArg");
|
||||
|
||||
ObjectNotification::ObjectNotification(const std::shared_ptr<DdsHandler> &ddsHandler, const std::shared_ptr<DatabaseInterface> &db)
|
||||
: m_ddsHandler(ddsHandler)
|
||||
, m_db(db)
|
||||
, m_logger(getLogger("ObjectNotification"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ObjectNotification::~ObjectNotification() { m_ddsHandler->dts()->removeNomNotificationByKey(m_dataNotificationObject.id()); } // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Core::FunctionReplyObject ObjectNotification::createObject(const NomNotification &data)
|
||||
{
|
||||
m_dataNotificationObject = data;
|
||||
|
||||
if (data.id() <= 0)
|
||||
{
|
||||
Database::NomNotification dbDataNotification = toDbData(data);
|
||||
dbDataNotification.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
||||
DBTransaction trans(m_db->database());
|
||||
if (!m_db->insert(dbDataNotification))
|
||||
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting NomNotification-data into database"));
|
||||
|
||||
// Neue DB Id in lokale Struktur uebernehmen
|
||||
m_dataNotificationObject.id(dbDataNotification.id);
|
||||
DEBUG_LOG(m_logger) << "New NotificationId: " << dbDataNotification.id;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Handle Address for notificationId:" << dbDataNotification.id << " number of depending recipients: " << data.recipientIds().size();
|
||||
|
||||
// Behandlung von Recipients
|
||||
for (size_t i = 0; i < data.recipientIds().size(); ++i)
|
||||
{
|
||||
Address &recipientAddress = m_dataNotificationObject.recipientIds()[i];
|
||||
Database::NomAddress dbDataRecipientAddr = toDbData(recipientAddress);
|
||||
|
||||
// Struct Address vorbereiten
|
||||
dbDataRecipientAddr.notificationId = dbDataNotification.id; // FK auf NotificationId
|
||||
dbDataRecipientAddr.id = 0;
|
||||
dbDataRecipientAddr.isRead = false;
|
||||
dbDataRecipientAddr.isSender = false;
|
||||
if (!m_db->insert(dbDataRecipientAddr))
|
||||
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting RecipientAddress-data into database"));
|
||||
// Neue DB Id in lokale Struktur uebernehmen
|
||||
recipientAddress.id(dbDataRecipientAddr.id);
|
||||
}
|
||||
|
||||
Address &senderAddress = m_dataNotificationObject.sender();
|
||||
Database::NomAddress dbDataSenderAddr = toDbData(senderAddress);
|
||||
|
||||
// Struct Address vorbereiten
|
||||
dbDataSenderAddr.notificationId = dbDataNotification.id; // FK auf NotificationId
|
||||
dbDataSenderAddr.isRead = false;
|
||||
dbDataSenderAddr.isSender = true;
|
||||
dbDataSenderAddr.id = 0;
|
||||
if (!m_db->insert(dbDataSenderAddr))
|
||||
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting SenderAddress-data into database"));
|
||||
// Neue DB Id in lokale Struktur uebernehmen
|
||||
senderAddress.id(dbDataSenderAddr.id);
|
||||
|
||||
trans.commit();
|
||||
}
|
||||
|
||||
// Publish Data via DTS
|
||||
onPublishData();
|
||||
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id());
|
||||
|
||||
} // end of createObject()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString ObjectNotification::contentArgsToJson()
|
||||
{
|
||||
int i = 1;
|
||||
QJsonArray jsonArray;
|
||||
|
||||
for (const std::string& arg : qAsConst(m_dataNotificationObject.contentArgs()))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << ".arg() ersetzt immer den kleinsten freien Platzhalter"
|
||||
<< ", arg=" << arg;
|
||||
QJsonObject argObj;
|
||||
argObj[CONTENT_ID] = i;
|
||||
argObj[CONTENT_ARG] = QString::fromStdString(arg);
|
||||
jsonArray.append(argObj);
|
||||
i++;
|
||||
}
|
||||
QJsonObject mainObject;
|
||||
mainObject[TRANSLATION_ARGS] = jsonArray;
|
||||
|
||||
QJsonDocument doc(mainObject);
|
||||
DEBUG_LOG(m_logger) << "ObjectNotification::contentArgsToJson properties=" << QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||
}
|
||||
|
||||
std::vector<std::string> ObjectNotification::jsonToContentArgs(const QString &jsonString)
|
||||
{
|
||||
//DEBUG_LOG(m_logger) << "jsonToContentArgs jsonString=" << jsonString;
|
||||
std::vector<std::string> result;
|
||||
// 1. String parsen
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
|
||||
if (!doc.isObject()) {
|
||||
//WARNING_LOG(m_logger) << "properties: Invalid JSON-Object";
|
||||
return result;
|
||||
}
|
||||
|
||||
QJsonObject hauptObjekt = doc.object();
|
||||
|
||||
// 2. Das Array aus "translationsArgs" herausholen
|
||||
if (!hauptObjekt.contains(TRANSLATION_ARGS) || !hauptObjekt[TRANSLATION_ARGS].isArray()) {
|
||||
//WARNING_LOG(m_logger) << "Missing or invalid 'translationsArgs' key (must be an array).";
|
||||
return result;
|
||||
}
|
||||
QJsonArray jsonArray = hauptObjekt[TRANSLATION_ARGS].toArray();
|
||||
|
||||
for ( int gesuchteId = 1; gesuchteId <= jsonArray.size(); gesuchteId++)
|
||||
{
|
||||
// 3. Für schnellen Zugriff nach ID indizieren
|
||||
QHash<int, QJsonObject> sucheMap;
|
||||
for (const QJsonValue &wert : qAsConst(jsonArray))
|
||||
{
|
||||
QJsonObject obj = wert.toObject();
|
||||
int id = obj[CONTENT_ID].toInt();
|
||||
sucheMap[id] = obj;
|
||||
}
|
||||
|
||||
// 4. Zugriff über die ID testen
|
||||
if (sucheMap.contains(gesuchteId)) {
|
||||
QJsonObject treffer = sucheMap[gesuchteId];
|
||||
//DEBUG_LOG(m_logger) << "ID" << gesuchteId << "gefunden!";
|
||||
//DEBUG_LOG(m_logger) << "Inhalt:" << treffer[CONTENT_ARG].toString();
|
||||
QString contentStr = treffer[CONTENT_ARG].toString();
|
||||
result.emplace_back(contentStr.toStdString());
|
||||
} else {
|
||||
//qDebug() << "ID" << gesuchteId << "nicht im System.";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ObjectNotification::readReceipt(const ReadReceipt &data, int notificationId)
|
||||
{
|
||||
if (!isValid())
|
||||
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Object not valid/blocked"));
|
||||
|
||||
Database::NomNotification dbDataNotification = toDbData(m_dataNotificationObject);
|
||||
|
||||
Database::NomAddress dbDataAddr;
|
||||
|
||||
for (const Address &recipientAddr : qAsConst(m_dataNotificationObject.recipientIds()))
|
||||
{
|
||||
if (data.operatorId() > 0 && recipientAddr.addressType() == AddressType_def::Operator && recipientAddr.addressId() != data.operatorId())
|
||||
continue;
|
||||
|
||||
if (data.workstationId() > 0 && recipientAddr.addressType() == AddressType_def::Workstation && recipientAddr.addressId() != data.workstationId())
|
||||
continue;
|
||||
|
||||
dbDataAddr = toDbData(recipientAddr);
|
||||
DEBUG_LOG(m_logger) << "Found Operator " << data.operatorId() << " with repicpentID " << dbDataAddr.id;
|
||||
dbDataAddr.notificationId = dbDataNotification.id;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (dbDataAddr.id <= 0)
|
||||
return Core::FunctionReplyObject(data.addressId(), tr_lts("dds", "No Address found"));
|
||||
|
||||
dbDataAddr.isRead = true;
|
||||
|
||||
DBTransaction trans(m_db->database());
|
||||
// NomNotification shall be marked as processed
|
||||
if (data.processed())
|
||||
{
|
||||
// but hasn't been so yet
|
||||
if (dbDataNotification.processed <= 0)
|
||||
{
|
||||
dbDataNotification.processed = dbDataAddr.id;
|
||||
dbDataNotification.processTime = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
if (dbDataNotification.priorityId != dbDataNotification.processedPriority)
|
||||
dbDataNotification.priorityId = dbDataNotification.processedPriority;
|
||||
|
||||
if (!m_db->update(dbDataNotification))
|
||||
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Error updating notification-data"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Notification already processed id=" << notificationId;
|
||||
return Core::FunctionReplyObject(dbDataNotification.processed, {}, {}, tr_lts("dds", "Notification already processed"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_db->update(dbDataAddr))
|
||||
return Core::FunctionReplyObject(dbDataAddr.id, tr_lts("dds", "Error updating address-data into database"));
|
||||
|
||||
trans.commit();
|
||||
|
||||
INFO_LOG(m_logger) << "Data changed for NotificationId: " << m_dataNotificationObject.id();
|
||||
|
||||
const std::vector<Address> recipients = m_dataNotificationObject.recipientIds();
|
||||
const Address sender = m_dataNotificationObject.sender();
|
||||
m_dataNotificationObject = toDdsData(dbDataNotification);
|
||||
m_dataNotificationObject.sender(sender);
|
||||
|
||||
for (const Address &addr : qAsConst(recipients))
|
||||
{
|
||||
if (addr.id() == dbDataAddr.id)
|
||||
m_dataNotificationObject.recipientIds().push_back(toDdsData(dbDataAddr));
|
||||
else
|
||||
m_dataNotificationObject.recipientIds().push_back(addr);
|
||||
}
|
||||
|
||||
// Publish Data via DTS
|
||||
onPublishData();
|
||||
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id());
|
||||
} // end of updateObject()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Core::FunctionReplyObject ObjectNotification::deleteMessage(const DeleteMessage &data, int notificationId)
|
||||
{
|
||||
if (!isValid())
|
||||
return Core::FunctionReplyObject(notificationId, tr_lts("dds", "Object not valid/blocked"));
|
||||
|
||||
Database::NomNotification dbDataNotification = toDbData(m_dataNotificationObject);
|
||||
|
||||
Database::NomAddress dbDataAddr;
|
||||
|
||||
for (const Address &recipientAddr : qAsConst(m_dataNotificationObject.recipientIds()))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "recipientAddr="
|
||||
<< ", id: " << recipientAddr.id() << ", addressId: " << recipientAddr.addressId() << ", isDeleted: " << recipientAddr.isDeleted();
|
||||
if (data.operatorId() > 0 && recipientAddr.addressType() == AddressType_def::Operator && recipientAddr.addressId() != data.operatorId())
|
||||
continue;
|
||||
|
||||
if (data.workstationId() > 0 && recipientAddr.addressType() == AddressType_def::Workstation && recipientAddr.addressId() != data.workstationId())
|
||||
continue;
|
||||
|
||||
dbDataAddr = toDbData(recipientAddr);
|
||||
dbDataAddr.notificationId = dbDataNotification.id;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (dbDataAddr.id <= 0)
|
||||
return Core::FunctionReplyObject(data.addressId(), tr_lts("dds", "No Address found"));
|
||||
|
||||
dbDataAddr.isDeleted = true;
|
||||
|
||||
DBTransaction trans(m_db->database());
|
||||
|
||||
if (!m_db->update(dbDataAddr))
|
||||
return Core::FunctionReplyObject(dbDataAddr.id, tr_lts("dds", "Error updating address-data into database"));
|
||||
|
||||
trans.commit();
|
||||
|
||||
INFO_LOG(m_logger) << "Data changed for NotificationId: " << m_dataNotificationObject.id();
|
||||
|
||||
std::vector<Address> recipients = m_dataNotificationObject.recipientIds();
|
||||
Address sender = m_dataNotificationObject.sender();
|
||||
m_dataNotificationObject = toDdsData(dbDataNotification);
|
||||
m_dataNotificationObject.sender(sender);
|
||||
|
||||
for (const Address &addr : qAsConst(recipients))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "addr="
|
||||
<< ", id: " << addr.id() << ", addressId: " << addr.addressId() << ", isDeleted: " << addr.isDeleted();
|
||||
|
||||
if (addr.id() == dbDataAddr.id)
|
||||
m_dataNotificationObject.recipientIds().push_back(toDdsData(dbDataAddr));
|
||||
else
|
||||
m_dataNotificationObject.recipientIds().push_back(addr);
|
||||
}
|
||||
|
||||
// Publish Data via DTS
|
||||
onPublishData();
|
||||
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id());
|
||||
} // end of updateObject()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Core::FunctionReplyObject ObjectNotification::deleteObject(const DeleteMessage &data, int notificationId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ObjectNotification::deleteObject"
|
||||
<< ", notificationId: " << notificationId << ", addressId: " << data.addressId() << ", operatorId: " << data.operatorId()
|
||||
<< ", workstationId: " << data.workstationId();
|
||||
deleteMessage(data, notificationId);
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id());
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ObjectNotification::removeObject()
|
||||
{
|
||||
if (!m_db->removeNomNotification(m_dataNotificationObject.id()))
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id(), tr_lts("dds", "NomNotification with id %1 can not be removed from DB"))
|
||||
.arg(m_dataNotificationObject.id());
|
||||
|
||||
if (!m_ddsHandler->dts()->removeNomNotificationByKey(m_dataNotificationObject.id()))
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id(), tr_lts("dds", "NomNotification with id %1 can not be removed from DDS"))
|
||||
.arg(m_dataNotificationObject.id());
|
||||
|
||||
return Core::FunctionReplyObject(m_dataNotificationObject.id());
|
||||
} // end of removeObject()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ObjectNotification::isValid() const { return m_dataNotificationObject.id() > 0; } // end of isValid()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ObjectNotification::onPublishData()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Publish NomNotification-data to dds notificationId:" << m_dataNotificationObject.id();
|
||||
|
||||
if (!m_ddsHandler->dts()->publish(m_dataNotificationObject))
|
||||
WARNING_LOG(m_logger) << "Error publishing NomNotification-data to dds";
|
||||
|
||||
} // end of onPublishData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// convert methods
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// NotificationManagement::NomNotification => Database::NomNotification
|
||||
Database::NomNotification ObjectNotification::toDbData(const NomNotification &ddsData)
|
||||
{
|
||||
Database::NomNotification dbData;
|
||||
|
||||
dbData.id = ddsData.id();
|
||||
dbData.exerciseId = ddsData.exerciseId();
|
||||
dbData.content = QString::fromStdString(ddsData.content());
|
||||
QString properties = contentArgsToJson();
|
||||
dbData.properties = properties;
|
||||
dbData.title = QString::fromStdString(ddsData.title());
|
||||
dbData.messageType = ddsData.messageType().underlying();
|
||||
dbData.notificationType = ddsData.notificationType().underlying();
|
||||
dbData.processTime = ddsData.processTime();
|
||||
dbData.processed = ddsData.processed();
|
||||
dbData.processedPriority = ddsData.processedPriority();
|
||||
dbData.expiryTime = ddsData.expiryTime();
|
||||
dbData.priorityId = ddsData.priority();
|
||||
dbData.timeStamp = ddsData.timeStamp();
|
||||
|
||||
return dbData;
|
||||
} // end of toDbData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Database::NomNotification => NotificationManagement::NomNotification
|
||||
NomNotification ObjectNotification::toDdsData(const Database::NomNotification &dbData)
|
||||
{
|
||||
NomNotification ddsData;
|
||||
|
||||
ddsData.id(dbData.id);
|
||||
ddsData.content(dbData.content.toStdString());
|
||||
std::vector< std::string > contentArgs = jsonToContentArgs(dbData.properties);
|
||||
ddsData.contentArgs(contentArgs);
|
||||
ddsData.title(dbData.title.toStdString());
|
||||
ddsData.messageType(static_cast<NotificationManagement::MessageType::inner_enum>(dbData.messageType));
|
||||
ddsData.notificationType(static_cast<NotificationManagement::NotificationType::inner_enum>(dbData.notificationType));
|
||||
ddsData.timeStamp(dbData.timeStamp);
|
||||
ddsData.priority(dbData.priorityId);
|
||||
ddsData.exerciseId(dbData.exerciseId);
|
||||
ddsData.expiryTime(dbData.expiryTime);
|
||||
ddsData.processTime(dbData.processTime);
|
||||
ddsData.processed(dbData.processed);
|
||||
ddsData.processedPriority(dbData.processedPriority.underlying());
|
||||
|
||||
return ddsData;
|
||||
} // end of toDdsData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// NotificationManagement::Address => Database::NomAddress
|
||||
Database::NomAddress ObjectNotification::toDbData(const Address &ddsData)
|
||||
{
|
||||
Database::NomAddress dbData;
|
||||
|
||||
dbData.id = ddsData.id();
|
||||
dbData.addressId = ddsData.addressId();
|
||||
dbData.addressSubId = ddsData.addressSubId();
|
||||
dbData.addressSubSubId = ddsData.addressSubSubId();
|
||||
dbData.addressTypeId = ddsData.addressType().underlying();
|
||||
dbData.isRead = ddsData.isRead();
|
||||
dbData.isDeleted = ddsData.isDeleted();
|
||||
dbData.name = QString::fromStdString(ddsData.name());
|
||||
|
||||
return dbData;
|
||||
} // end of toDbData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Database::NomAddress => NotificationManagement::Address
|
||||
Address ObjectNotification::toDdsData(const Database::NomAddress &dbData)
|
||||
{
|
||||
Address ddsData;
|
||||
|
||||
ddsData.id(dbData.id);
|
||||
ddsData.addressType(dbData.addressTypeId);
|
||||
ddsData.name(dbData.name.toStdString());
|
||||
ddsData.addressId(dbData.addressId);
|
||||
ddsData.addressSubId(dbData.addressSubId);
|
||||
ddsData.addressSubSubId(dbData.addressSubSubId);
|
||||
ddsData.isRead(dbData.isRead);
|
||||
ddsData.isDeleted(dbData.isDeleted);
|
||||
|
||||
return ddsData;
|
||||
} // end of toDdsData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
} // namespace NotificationManagement
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* NomNotification object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
//#include "nom_db.h"
|
||||
#include <DDS/Core/function_reply_object.h>
|
||||
|
||||
// Generated
|
||||
#include <NotificationManagement/nom_db.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
class ObjectNotification final
|
||||
{
|
||||
public:
|
||||
explicit ObjectNotification(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db);
|
||||
|
||||
~ObjectNotification();
|
||||
|
||||
Core::FunctionReplyObject createObject(const NomNotification &data);
|
||||
Core::FunctionReplyObject readReceipt(const ReadReceipt &data, int notificationId);
|
||||
Core::FunctionReplyObject deleteMessage(const DeleteMessage &data, int notificationId);
|
||||
Core::FunctionReplyObject deleteObject(const DeleteMessage &data, int notificationId);
|
||||
Core::FunctionReplyObject removeObject();
|
||||
|
||||
Core::FunctionReplyObject setUsed(bool isUsed);
|
||||
|
||||
qint32 id() const { return m_dataNotificationObject.id(); }
|
||||
NomNotification notification() const { return m_dataNotificationObject; }
|
||||
QString title() const { return QString::fromStdString(m_dataNotificationObject.title()); }
|
||||
|
||||
bool isValid() const;
|
||||
bool isUsed() const;
|
||||
|
||||
|
||||
// convert methods
|
||||
Database::NomNotification toDbData(const NomNotification &ddsData); // dds -> db
|
||||
static NomNotification toDdsData(const Database::NomNotification &dbData); // db -> dds
|
||||
|
||||
static Database::NomAddress toDbData(const Address &ddsData); // dds -> db
|
||||
static Address toDdsData(const Database::NomAddress &dbData); // db -> dds
|
||||
|
||||
private:
|
||||
void onPublishData();
|
||||
QString contentArgsToJson();
|
||||
static std::vector<std::string> jsonToContentArgs(const QString &properties);
|
||||
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<DatabaseInterface> m_db;
|
||||
NomNotification m_dataNotificationObject;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
} // namespace NotificationManagement
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Settings for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, ESZS, 2025-06-23
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
class NGLSettingsClass : public NGL::Settings
|
||||
{
|
||||
public:
|
||||
NGLSettingsClass()
|
||||
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
|
||||
{}
|
||||
static void setIniFile(const QString &fn)
|
||||
{
|
||||
s_iniFile = fn;
|
||||
}
|
||||
static QString s_iniFile;
|
||||
};
|
||||
QString NGLSettingsClass::s_iniFile;
|
||||
Q_GLOBAL_STATIC(NGLSettingsClass, s)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NGL::Settings *Settings::settings()
|
||||
{
|
||||
return s();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::setIniFile(const QString &ini)
|
||||
{
|
||||
NGLSettingsClass::setIniFile(ini);
|
||||
}
|
||||
|
||||
qint64 Settings::expiryIntervalMSec()
|
||||
{
|
||||
return settings()->settings()->value(QStringLiteral("NOM/expiryIntervalMSec"), 2 * 24 * 60 * 60 * 1000 ).toLongLong(); // 2 days default
|
||||
}
|
||||
|
||||
qint64 Settings::removeTimerIntervalMSec()
|
||||
{
|
||||
return settings()->settings()->value(QStringLiteral("NOM/removeTimerIntervalMSec"), 10 * 1000 ).toLongLong(); // 10 seconds default
|
||||
}
|
||||
|
||||
// Priorities: Highest = 1, High = 2, Normal = 3, Low = 4
|
||||
int Settings::notificationPriority()
|
||||
{
|
||||
return settings()->settings()->value(QStringLiteral("NOM/notificationPriority"),3 ).toInt();
|
||||
}
|
||||
} // namespace NotificationManagement
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Settings for NotificationManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
|
||||
qint64 expiryIntervalMSec();
|
||||
qint64 removeTimerIntervalMSec();
|
||||
int notificationPriority();
|
||||
}
|
||||
|
||||
} // namespace NotificationManagement
|
||||
Reference in new issue
Block a user