Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+160
@@ -0,0 +1,160 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
INCLUDE(MacroRTIDDSGen)
|
||||
INCLUDE(MacroCodeGenIdl)
|
||||
|
||||
SET(xml_FILE msg_service.xml)
|
||||
|
||||
#
|
||||
# --- Library svcMsgCommon --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_common
|
||||
msg_export.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
# Generate msg_enums.idl / msg.idl
|
||||
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
|
||||
# Generate msg_db_impl.cpp/.h, msg_db.h
|
||||
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
|
||||
|
||||
# Generate *.cpp/*.hpp from idl
|
||||
RTIDDSGEN(SRCS_common msg_enums.idl)
|
||||
RTIDDSGEN(SRCS_common msg.idl)
|
||||
|
||||
# Generate msg_dt[s,c]_types.h, msg_ft[s,c]_types.h
|
||||
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
|
||||
# generate msg_[d|f]tc.h
|
||||
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS svcMsgCommon SHARED ${SRCS_common})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcMsgCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(svcMsgCommon
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
ddscore
|
||||
ngldb
|
||||
LtsCommandLineParser
|
||||
NGLLogger
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcMsgCommon)
|
||||
|
||||
#
|
||||
# --- Library svcMsgClient --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_client
|
||||
msg_export.h
|
||||
)
|
||||
# generate msg_[d|f]tc_impl.[cpp|h]
|
||||
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS svcMsgClient SHARED ${SRCS_client})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcMsgClient
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcMsgClient
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
PUBLIC
|
||||
svcMsgCommon
|
||||
ddsftc
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcMsgClient)
|
||||
|
||||
#
|
||||
# --- Library svcMsgServer --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_server
|
||||
msg_export.h
|
||||
)
|
||||
# generate msg_[d|f]ts.h, msg_[d|f]ts_impl.[cpp|h]
|
||||
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV svcMsgServer SHARED ${SRCS_server})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcMsgServer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcMsgServer
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
ddsfts
|
||||
PUBLIC
|
||||
svcMsgCommon
|
||||
ngldb
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcMsgServer)
|
||||
|
||||
#
|
||||
# --- Topic Type Plugin --------------------------------------------------------------
|
||||
#
|
||||
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
|
||||
|
||||
#
|
||||
# --- Executable svcMessaging (sMSG) -------------------------------------------------
|
||||
#
|
||||
SET(SRCS_exe
|
||||
main.cpp
|
||||
main_handler.cpp
|
||||
main_handler.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
exercise_handler.cpp
|
||||
exercise_handler.h
|
||||
exercises_handler.cpp
|
||||
exercises_handler.h
|
||||
handler_operator_message.cpp
|
||||
handler_operator_message.h
|
||||
log4cxx_msg.props
|
||||
${xml_FILE}
|
||||
)
|
||||
|
||||
# Generate msg.sql, msg.xml
|
||||
CODEGEN_SQL(SRCS_exe ${xml_FILE})
|
||||
|
||||
NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
NGL_ADD_EXECUTABLE(AAR SV svcMessaging ${SRCS_exe})
|
||||
NGL_TARGET_LINK_LIBRARIES(svcMessaging
|
||||
Qt5::Core
|
||||
svcMsgCommon
|
||||
svcMsgServer
|
||||
svcTabClient
|
||||
svcOpmClient
|
||||
svcOssClient
|
||||
svcPpmClient
|
||||
svcCoreClient
|
||||
ddsconnector
|
||||
nglsettings
|
||||
ProjectConfig
|
||||
NGLLogger
|
||||
nglcoreapplication
|
||||
ngltools
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcMessaging)
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_msg.props DESTINATION bin)
|
||||
NGL_ADD_TARGET_LINK(svcMessaging sMSG)
|
||||
|
||||
# Uncomment if necessary
|
||||
#ADD_SUBDIRECTORY(UnitTests)
|
||||
ADD_SUBDIRECTORY(ModuleTests)
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
|
||||
IF(BUILD_TESTING)
|
||||
IF(TARGET svcMsgClient AND TARGET svcTabServer)
|
||||
|
||||
####################################
|
||||
# Message Test
|
||||
####################################
|
||||
|
||||
SET(SRCS_TEST_MSG
|
||||
msg_tests.cpp
|
||||
)
|
||||
SET(HDRS_TEST_MSG
|
||||
msg_tests.h
|
||||
)
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(msgTests
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
# Testing FunctionTopic Functionality (FTC)
|
||||
ADD_EXECUTABLE(msgTests ${SRCS_TEST_MSG} ${HDRS_TEST_MSG})
|
||||
TARGET_LINK_LIBRARIES(msgTests
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
RTI::nddscpp2
|
||||
svcMsgClient
|
||||
svcTabClient
|
||||
svcTabServer
|
||||
svcCoreClient
|
||||
LtsCommandLineParser
|
||||
ddsconnector
|
||||
nglcoreapplication
|
||||
)
|
||||
IF(NOT BUILD_RPM)
|
||||
NGL_INSTALL(AAR SV TARGETS msgTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV FILES ../log4cxx_msg.props DESTINATION bin/test)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
+441
@@ -0,0 +1,441 @@
|
||||
/**
|
||||
* Msg Function Topic Module Test
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "msg_tests.h"
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <Messaging/msg_ftc.h>
|
||||
|
||||
/* ----------------------------------------------------------------------------------
|
||||
* HOW TO RUN THE TESTS
|
||||
* ----------------------------------------------------------------------------------
|
||||
* 0. Preconditions:
|
||||
* Start with an empty database (BUILD)
|
||||
* make db
|
||||
*
|
||||
* Preconditions:
|
||||
* For test 1, 2, 3:
|
||||
* - User 1,2,3 in DB
|
||||
*
|
||||
* For test 4 and 5:
|
||||
* - exercise with Observer/Controller ( ppm.ppm_equipment_type = 20 )equipmentNumber 2500, 2501
|
||||
* - empty table msg.msg_message_operator_data
|
||||
*
|
||||
* Please start in order 1, 2, 3, ...
|
||||
*
|
||||
* Start services: (SV)
|
||||
* ./bin/svcMessaging &
|
||||
* -t 1 = CreateOperatorMessage
|
||||
* -t 2 = SetIsRead
|
||||
* -t 3 = SetDeleted
|
||||
* -t 4 = Send to Tetra
|
||||
* -t 5 = receive from Tetra
|
||||
*/
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
MsgTests::MsgTests(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_testId(0)
|
||||
, m_bTestsSuccessful(true)
|
||||
, m_messageCount(0)
|
||||
, m_msgIdSendMessage(1) // Result from last test
|
||||
, m_msgIdRecvMessage(3) // Result from last test
|
||||
, m_numberMessages(3) // Result from last test
|
||||
, m_testStep(TestCase::CreateOperator)
|
||||
, m_logger(getLogger("MsgTests"))
|
||||
{}
|
||||
|
||||
MsgTests::~MsgTests()
|
||||
{}
|
||||
|
||||
bool MsgTests::init(int domainId, int testId)
|
||||
{
|
||||
INFO_LOG(m_logger) << "init begin";
|
||||
|
||||
m_testId = testId;
|
||||
|
||||
m_ddsConnector.reset(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::Any));
|
||||
if (!m_ddsConnector->init())
|
||||
return false;
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
m_ftc = Messaging::Interface::Ftc::create(m_ddsConnector);
|
||||
bool bRet = m_ftc->enableAll();
|
||||
|
||||
m_dtc = Messaging::Interface::Dtc::create(m_ddsConnector);
|
||||
bRet &= m_dtc->enableAll();
|
||||
|
||||
return bRet;
|
||||
} // init
|
||||
|
||||
void MsgTests::startTest()
|
||||
{
|
||||
INFO_LOG(m_logger) << "startTest m_testId=" << m_testId;
|
||||
if (m_testId <= 1) // CreateOperatorMessage
|
||||
{
|
||||
m_testStep = TestCase::CreateOperator;
|
||||
QTimer::singleShot(0, this, &MsgTests::tryCreateOperatorMessage);
|
||||
}
|
||||
else if (m_testId == 2) // SetIsRead
|
||||
{
|
||||
m_testStep = TestCase::SetIsRead;
|
||||
MsgTests::markMessageAsRead();
|
||||
}
|
||||
else if (m_testId == 3) // SetDeleted
|
||||
{
|
||||
m_testStep = TestCase::SetDeleted;
|
||||
MsgTests::markMessageAsDeleted();
|
||||
}
|
||||
else if (m_testId == 4) // send to TETRA
|
||||
{
|
||||
m_testStep = TestCase::SendToTetra;
|
||||
QTimer::singleShot(0, this, &MsgTests::tryCreateOperatorMessage);
|
||||
}
|
||||
else if (m_testId == 5) // receive from TETRA
|
||||
{
|
||||
m_testStep = TestCase::ReceiveFromTetra;
|
||||
QTimer::singleShot(0, this, &MsgTests::tryCreateOperatorMessage);
|
||||
}
|
||||
} // startTest
|
||||
|
||||
void MsgTests::tryCreateOperatorMessage()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send createRequest Operator Message";
|
||||
Messaging::AddressType receiverType;
|
||||
Messaging::AddressType senderType;
|
||||
|
||||
std::vector<int32_t> recipientIds;
|
||||
int32_t sender = 3;
|
||||
std::string subject = "subject Operator";
|
||||
recipientIds.resize(2);
|
||||
int exerciseId = 42;
|
||||
switch (m_testStep)
|
||||
{
|
||||
case TestCase::CreateOperator:
|
||||
{
|
||||
receiverType = Messaging::AddressType_def::type::Operator;
|
||||
senderType = Messaging::AddressType_def::type::Operator;
|
||||
m_expectedMessage = "msg Operator: " + QDateTime::currentDateTimeUtc().toString().toStdString();
|
||||
recipientIds[0] = 1;
|
||||
recipientIds[1] = 2;
|
||||
break;
|
||||
}
|
||||
case TestCase::SendToTetra:
|
||||
{
|
||||
receiverType = Messaging::AddressType_def::type::ObserverController;
|
||||
senderType = Messaging::AddressType_def::type::Operator;
|
||||
m_expectedMessage = "msg to OC: " + QDateTime::currentDateTimeUtc().toString().toStdString();
|
||||
recipientIds[0] = 57; // Participant id for eq-number 2500
|
||||
recipientIds[1] = 58; // Participant id for eq-number 2501
|
||||
break;
|
||||
}
|
||||
case TestCase::ReceiveFromTetra:
|
||||
{
|
||||
receiverType = Messaging::AddressType_def::type::Operator;
|
||||
senderType = Messaging::AddressType_def::type::ObserverController;
|
||||
m_expectedMessage = "msg from OC: " + QDateTime::currentDateTimeUtc().toString().toStdString();
|
||||
sender = 2500;
|
||||
recipientIds[0] = 1;
|
||||
recipientIds[1] = 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!m_ftc->createOperatorMessageRequest(CreateOperatorMessageRequest(recipientIds, exerciseId, sender, subject, m_expectedMessage, senderType, receiverType), this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting create data";
|
||||
failExit();
|
||||
}
|
||||
} // tryCreateOperatorMessage
|
||||
|
||||
void MsgTests::checkMessageOnDdsAfterCreate()
|
||||
{
|
||||
// read from dds, check if data is as expected
|
||||
m_messageCount = 0;
|
||||
|
||||
m_dtc->waitForHistoricalDataOperatorMessage();
|
||||
const QMap<int, Messaging::OperatorMessage> messages = m_dtc->operatorMessages();
|
||||
for (const auto &om : messages)
|
||||
{
|
||||
INFO_LOG(m_logger) << "checkMessageOnDdsAfterCreate om.id = " << om.id();
|
||||
|
||||
if (om.message() == m_expectedMessage)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "senderId: " << om.senderId() << ", recipientId: " << om.recipientId();
|
||||
if (om.senderId() != 0 && om.recipientId() == 0)
|
||||
{
|
||||
m_msgIdSendMessage = om.id();
|
||||
DEBUG_LOG(m_logger) << "m_msgIdSendMessage=" << m_msgIdSendMessage;
|
||||
++m_messageCount;
|
||||
}
|
||||
|
||||
if (om.senderId() != 0 && om.recipientId() != 0)
|
||||
{
|
||||
m_msgIdRecvMessage = om.id();
|
||||
DEBUG_LOG(m_logger) << "m_msgIdRecvMessage=" << m_msgIdRecvMessage;
|
||||
++m_messageCount;
|
||||
}
|
||||
}
|
||||
// msg count == 3 -> one for sender, two for receiver
|
||||
if (m_messageCount == 3)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Success: receiving messages - got: " << m_messageCount << " expected: 3";
|
||||
ExitSuccess();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_testStep == TestCase::ReceiveFromTetra || m_testStep == TestCase::SendToTetra)
|
||||
{
|
||||
ExitSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "Error receiving messages - got: " << m_messageCount << " expected: 3";
|
||||
failExit();
|
||||
} // checkMessageOnDdsAfterCreate
|
||||
|
||||
void MsgTests::checkMessageOnDdsAfterModify()
|
||||
{
|
||||
// read from dds, check if data is as expected
|
||||
int isRead = 0;
|
||||
INFO_LOG(m_logger) << "checkMessageOnDdsAfterModify";
|
||||
m_dtc->waitForHistoricalDataOperatorMessage();
|
||||
const QMap<int, Messaging::OperatorMessage> messages = m_dtc->operatorMessages();
|
||||
switch (m_testStep)
|
||||
{
|
||||
case TestCase::SetIsRead:
|
||||
{
|
||||
for (const auto &om : messages)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "om.id()=" << om.id() << " om.isRead()=" << om.isRead();
|
||||
if (om.id() == m_msgIdRecvMessage && om.isRead() == true)
|
||||
++isRead;
|
||||
}
|
||||
if (isRead == 1)
|
||||
{
|
||||
INFO_LOG(m_logger) << "modify messages isRead = TRUE: Success ";
|
||||
ExitSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "Error modify messages - got: " << isRead << " expected: 1";
|
||||
failExit();
|
||||
break;
|
||||
}
|
||||
case TestCase::SetDeleted:
|
||||
{
|
||||
// Message removed from DDS
|
||||
|
||||
DEBUG_LOG(m_logger) << "m_numberMessages= " << m_numberMessages << " messages.size()= " << messages.size();
|
||||
if (m_numberMessages > messages.size())
|
||||
{
|
||||
INFO_LOG(m_logger) << "modify messages isDeleted = TRUE: Success ";
|
||||
ExitSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ERROR_LOG(m_logger) << "Error modify messages - got: " << messages.size() << " expected less than " << m_numberMessages;
|
||||
failExit();
|
||||
break;
|
||||
}
|
||||
case TestCase::SendToTetra:
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "SendToTetra reply m_numberMessages= " << m_numberMessages << " messages.size()= " << messages.size();
|
||||
ExitSuccess();
|
||||
break;
|
||||
}
|
||||
case TestCase::ReceiveFromTetra:
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ReceiveFromTetra reply m_numberMessages= " << m_numberMessages << " messages.size()= " << messages.size();
|
||||
ExitSuccess();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
INFO_LOG(m_logger) << "Nothing to do in this TestCase";
|
||||
}
|
||||
}
|
||||
} // checkMessageOnDdsAfterModify
|
||||
|
||||
void MsgTests::checkMessageOnDdsAfterDelete()
|
||||
{
|
||||
// read from dds, check if data is as expected
|
||||
int isDeleted = 0;
|
||||
INFO_LOG(m_logger) << "checkMessageOnDdsAfterModify";
|
||||
m_dtc->waitForHistoricalDataOperatorMessage();
|
||||
const QMap<int, Messaging::OperatorMessage> messages = m_dtc->operatorMessages();
|
||||
for (const auto &om : messages)
|
||||
{
|
||||
if (om.id() == m_msgIdRecvMessage && om.isDeleted() == true)
|
||||
++isDeleted;
|
||||
}
|
||||
if (isDeleted == 1)
|
||||
{
|
||||
INFO_LOG(m_logger) << "modify messages delete: Success ";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ERROR_LOG(m_logger) << "Error modify messages - got: " << isDeleted << " expected: 1";
|
||||
failExit();
|
||||
} // checkMessageOnDdsAfterDelete
|
||||
|
||||
void MsgTests::markMessageAsRead()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to mark Message as read m_msgIdRecvMessage =" << m_msgIdRecvMessage;
|
||||
|
||||
int32_t id = m_msgIdRecvMessage;
|
||||
bool isRead = true;
|
||||
bool isSend = false;
|
||||
bool isDeleted = false;
|
||||
|
||||
if (!m_ftc->modifyOperatorMessageRequest(ModifyOperatorMessageRequest(id, isRead, isSend, isDeleted), this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error mark Message as read";
|
||||
failExit();
|
||||
}
|
||||
} // markMessageAsRead
|
||||
|
||||
void MsgTests::markMessageAsDeleted()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to mark Message as deleted m_msgIdRecvMessage =" << m_msgIdRecvMessage;
|
||||
|
||||
int32_t id = m_msgIdRecvMessage;
|
||||
bool isRead = true;
|
||||
bool isSend = false;
|
||||
bool isDeleted = true;
|
||||
|
||||
m_dtc->waitForHistoricalDataOperatorMessage();
|
||||
DEBUG_LOG(m_logger) << "m_numberMessages =" << m_numberMessages;
|
||||
|
||||
if (!m_ftc->modifyOperatorMessageRequest(ModifyOperatorMessageRequest(id, isRead, isSend, isDeleted), this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error mark Message as deleted";
|
||||
failExit();
|
||||
}
|
||||
} // markMessageAsDeleted
|
||||
|
||||
void MsgTests::onCreateOperatorMessageReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onCreateOperatorMessageReply, error = " << replyObject.error();
|
||||
if (replyObject.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error creating new message - aborting";
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_testStep)
|
||||
{
|
||||
case TestCase::CreateOperator:
|
||||
case TestCase::SendToTetra:
|
||||
case TestCase::ReceiveFromTetra:
|
||||
// 1s - wait until data is delivered
|
||||
QTimer::singleShot(1000, this, &MsgTests::checkMessageOnDdsAfterCreate);
|
||||
break;
|
||||
default:
|
||||
INFO_LOG(m_logger) << "Nothing to do in this Case";
|
||||
}
|
||||
}
|
||||
} // onCreateOperatorMessageReply
|
||||
|
||||
void MsgTests::onModifyOperatorMessageReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onModifyOperatorMessageReply, error = " << replyObject.error();
|
||||
if (replyObject.error())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error modify message - aborting";
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1s - wait until data is delivered
|
||||
QTimer::singleShot(1000, this, &MsgTests::checkMessageOnDdsAfterModify);
|
||||
}
|
||||
} // onModifyOperatorMessageReply
|
||||
|
||||
/*
|
||||
void MsgTests::onSendEquipmentMessageReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "************** onSendEquipmentMessageReply TODO isRead = TRUE setzen: id = **********************";
|
||||
}
|
||||
|
||||
*/
|
||||
void MsgTests::failExit()
|
||||
{
|
||||
m_bTestsSuccessful = false;
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
} // failExit
|
||||
|
||||
void MsgTests::ExitSuccess()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "SUCCESS";
|
||||
m_bTestsSuccessful = true;
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
} // ExitSuccess
|
||||
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser()
|
||||
: LtsCommandLineParser()
|
||||
{
|
||||
addOption({ QStringList() << QLatin1String("t") << QLatin1String("testId")
|
||||
, QLatin1String("TestId.")
|
||||
, QLatin1String("Default: 0 (all tests)")
|
||||
, QLatin1String("0")
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
int testId() const { return isSet(QLatin1String("t")) ? value(QLatin1String("t")).toInt() : -1; }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("MSG", 0);
|
||||
|
||||
CmdLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
int iRet = -1;
|
||||
{
|
||||
std::unique_ptr<Messaging::MsgTests> msgTests(new Messaging::MsgTests);
|
||||
|
||||
if (!msgTests->init(options.domainId(), options.testId()))
|
||||
return iRet;
|
||||
|
||||
msgTests->startTest();
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
app.exec();
|
||||
|
||||
iRet = msgTests->testsSuccessful() ? 0 : 1;
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
} // main
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* ModuleTests for Msg
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Messaging/msg_dtc.h>
|
||||
#include <Messaging/msg_ftc.h>
|
||||
#include <Messaging/msg_ftc_types.h>
|
||||
#include <Messaging/logger.h>
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
enum class TestCase
|
||||
{
|
||||
CreateOperator = 0,
|
||||
SetIsRead = 1,
|
||||
SetDeleted = 2,
|
||||
SendToTetra = 3,
|
||||
ReceiveFromTetra = 4
|
||||
};
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
class MsgTests : public QObject
|
||||
, protected Messaging::Interface::Ftc::CreateOperatorMessageReplyHandler
|
||||
, protected Messaging::Interface::Ftc::ModifyOperatorMessageReplyHandler
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MsgTests(QObject *parent = nullptr);
|
||||
~MsgTests();
|
||||
|
||||
bool init(int domainId, int testId);
|
||||
|
||||
bool testsSuccessful() const
|
||||
{
|
||||
return m_bTestsSuccessful;
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
void startTest();
|
||||
protected Q_SLOTS:
|
||||
void tryCreateOperatorMessage();
|
||||
void checkMessageOnDdsAfterCreate();
|
||||
void checkMessageOnDdsAfterModify();
|
||||
void checkMessageOnDdsAfterDelete();
|
||||
void markMessageAsRead();
|
||||
void markMessageAsDeleted();
|
||||
protected:
|
||||
void onCreateOperatorMessageReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onModifyOperatorMessageReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void failExit();
|
||||
void ExitSuccess();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<Messaging::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<Messaging::Interface::Dtc> m_dtc;
|
||||
|
||||
int m_testId;
|
||||
bool m_bTestsSuccessful;
|
||||
std::string m_expectedMessage;
|
||||
int m_messageCount;
|
||||
int m_msgIdSendMessage;
|
||||
int m_msgIdRecvMessage;
|
||||
int m_numberMessages;
|
||||
TestCase m_testStep;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Messaging
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* 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 Messaging
|
||||
{
|
||||
|
||||
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 = Messaging::Interface::Dts::create(m_ddsConnector);
|
||||
bool bRet = m_ddsDts->enableAll();
|
||||
INFO_LOG(m_logger) << "Dts initialised";
|
||||
|
||||
// FTS
|
||||
m_ddsFts = Messaging::Interface::Fts::create(m_ddsConnector);
|
||||
bRet &= m_ddsFts->enableAll();
|
||||
INFO_LOG(m_logger) << "Fts initialised";
|
||||
|
||||
return bRet;
|
||||
} // end of init()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
qint64 DdsHandler::currentPartitionTime() const
|
||||
{
|
||||
return m_dtcCore->partitionTime().timeStamp();
|
||||
}
|
||||
|
||||
|
||||
} // Namespace Messaging
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-02
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <DDS/Core/topic_lock_master.h>
|
||||
#include <DDS/Core/core_dtc.h>
|
||||
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
|
||||
#include <Messaging/msg_dts.h>
|
||||
#include <Messaging/msg_fts.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
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<Messaging::Interface::Dts> dts() const { return m_ddsDts; }
|
||||
std::shared_ptr<Messaging::Interface::Fts> fts() const { return m_ddsFts; }
|
||||
|
||||
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<Messaging::Interface::Dts> m_ddsDts;
|
||||
std::shared_ptr<Messaging::Interface::Fts> m_ddsFts;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Send a function topic to TrainingAreabase in a specific exercise
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-12-13
|
||||
*/
|
||||
|
||||
|
||||
#include "exercise_handler.h"
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
ExerciseHandler::ExerciseHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, const int exerciseId)
|
||||
: m_ddsConnector(std::make_shared<DDSConnector::DdsConnector>(ddsConnector->getDomainId(), IDL::PartitionType::Exercise, exerciseId))
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_idleTimer(new QTimer(this))
|
||||
, m_logger(getLogger("ExerciseHandler"))
|
||||
{
|
||||
connect(m_idleTimer, &QTimer::timeout,
|
||||
this, &ExerciseHandler::exerciseHandlerIdleTimeout);
|
||||
m_idleTimer->setSingleShot(true);
|
||||
m_idleTimer->setInterval(60 * 60 * 1000); // 1h
|
||||
}
|
||||
|
||||
bool ExerciseHandler::init()
|
||||
{
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
DEBUG_LOG(m_logger) << "ExerciseHandler::init m_ddsConnector=" << m_ddsConnector
|
||||
<< " m_exerciseId=" << m_exerciseId;
|
||||
m_tabFtc = TrainingAreaBase::Interface::Ftc::create(m_ddsConnector);
|
||||
bool retVal = m_tabFtc->enableSendEquipmentMessage();
|
||||
if (!retVal)
|
||||
return false;
|
||||
|
||||
m_ossFtc = OcSituationServer::Interface::Ftc::create(m_ddsConnector);
|
||||
retVal = m_ossFtc->enableSendEquipmentMessageOc();
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool ExerciseHandler::sendEquipmentMessage(const TrainingAreaBase::SendEquipmentMessageRequest &request)
|
||||
{
|
||||
if (!m_tabFtc)
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "ExerciseHandler::sendEquipmentMessage: " << request;
|
||||
m_idleTimer->stop();
|
||||
return m_tabFtc->sendEquipmentMessageRequest(request, this);
|
||||
}
|
||||
|
||||
bool ExerciseHandler::sendOcEquipmentMessage(const OcSituationServer::SendEquipmentMessageRequest &request)
|
||||
{
|
||||
if (!m_ossFtc)
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "ExerciseHandler::sendOcEquipmentMessage: "<< request;
|
||||
m_idleTimer->stop();
|
||||
return m_ossFtc->sendEquipmentMessageOcRequest(request, this);
|
||||
}
|
||||
|
||||
int ExerciseHandler::exerciseId() const
|
||||
{
|
||||
return m_exerciseId;
|
||||
}
|
||||
|
||||
void ExerciseHandler::onSendEquipmentMessageReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"ExerciseHandler::onSendEquipmentMessageReply";
|
||||
m_idleTimer->start();
|
||||
if (replyObject.error())
|
||||
ERROR_LOG(m_logger) << replyObject();
|
||||
emit equipmentMessageReply(replyObject.id(), !replyObject.error());
|
||||
}
|
||||
|
||||
void ExerciseHandler::onSendEquipmentMessageOcReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"ExerciseHandler::onSendEquipmentMessageOcReply";
|
||||
m_idleTimer->start();
|
||||
if (replyObject.error())
|
||||
ERROR_LOG(m_logger) << replyObject();
|
||||
emit equipmentMessageOcReply(replyObject.id(), !replyObject.error());
|
||||
}
|
||||
} // namespace Messaging
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Send a function topic to TrainingAreabase in a specific exercise
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-12-13
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <TrainingAreaBase/tab_ftc.h>
|
||||
#include <OcSituationServer/oss_ftc.h>
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
class ExerciseHandler final : public QObject,
|
||||
public TrainingAreaBase::Interface::Ftc::SendEquipmentMessageReplyHandler,
|
||||
public OcSituationServer::Interface::Ftc::SendEquipmentMessageOcReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExerciseHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
||||
const int exerciseId);
|
||||
|
||||
bool init();
|
||||
bool sendEquipmentMessage(const TrainingAreaBase::SendEquipmentMessageRequest &request);
|
||||
bool sendOcEquipmentMessage(const OcSituationServer::SendEquipmentMessageRequest &request);
|
||||
int exerciseId() const;
|
||||
Q_SIGNALS:
|
||||
void exerciseHandlerIdleTimeout();
|
||||
void equipmentMessageReply(int msgId, bool sentSuccessful);
|
||||
void equipmentMessageOcReply(int replyId, bool sentSuccessful);
|
||||
private:
|
||||
void onSendEquipmentMessageReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onSendEquipmentMessageOcReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<TrainingAreaBase::Interface::Ftc> m_tabFtc;
|
||||
std::shared_ptr<OcSituationServer::Interface::Ftc> m_ossFtc;
|
||||
int m_exerciseId;
|
||||
QTimer *m_idleTimer; //<! timer to delete ExerciseHandler after n seconds when no longer needed
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace Messaging
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Get information about (O/C) participants to be able to send/receive messages for them
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-12-13
|
||||
*/
|
||||
|
||||
|
||||
#include "exercises_handler.h"
|
||||
#include "exercise_handler.h"
|
||||
|
||||
// subscribe to ex_* to gather
|
||||
// 1. PPM::EquipmentExerciseMapping
|
||||
// 2. TAB::EquipmentMessage
|
||||
// create ExerciseHandler per Exercise (on demand when a message should be send to an O/C)
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
ExercisesHandler::ExercisesHandler(const std::shared_ptr<DdsHandler> &ddsHandler)
|
||||
: m_ddsHandler(ddsHandler)
|
||||
, m_logger(getLogger("ExercisesHandler"))
|
||||
{
|
||||
}
|
||||
|
||||
ExercisesHandler::~ExercisesHandler()
|
||||
{
|
||||
qDeleteAll(m_exerciseHandler);
|
||||
}
|
||||
|
||||
bool ExercisesHandler::init()
|
||||
{
|
||||
m_ppmDtc = ParticipantManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector());
|
||||
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::equipmentExerciseMappingChanged,
|
||||
this, &ExercisesHandler::onEquipmentExerciseMappingChanged);
|
||||
|
||||
if (!m_ppmDtc->enableEquipmentExerciseMapping())
|
||||
return false;
|
||||
|
||||
ERROR_LOG(m_logger) << "# eem: " << m_ppmDtc->equipmentExerciseMappings().size();
|
||||
return true;
|
||||
}
|
||||
|
||||
int ExercisesHandler::findEquipmentNumber(int participantId, int exerciseId)
|
||||
{
|
||||
QPair<int,int> exePart;
|
||||
exePart.first = exerciseId;
|
||||
exePart.second = participantId;
|
||||
return m_participant2EquipNumber.value(exePart);
|
||||
}
|
||||
|
||||
bool ExercisesHandler::sendEquipmentMessage(const TrainingAreaBase::SendEquipmentMessageRequest &request)
|
||||
{
|
||||
if (request.equipmentNumbers().size() == 0)
|
||||
return false;
|
||||
const int equipmentNumber = request.equipmentNumbers().at(0);
|
||||
auto it = m_equipNo2ExerciseId.constFind(equipmentNumber);
|
||||
if (it == m_equipNo2ExerciseId.cend())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not send equipment message to training area - equipment number "
|
||||
<< equipmentNumber << " not known";
|
||||
return false;
|
||||
}
|
||||
ExerciseHandler *exH = exerciseHandlerForExerciseId(it.value());
|
||||
return exH->sendEquipmentMessage(request);
|
||||
}
|
||||
|
||||
bool ExercisesHandler::sendOcEquipmentMessage(const OcSituationServer::SendEquipmentMessageRequest &request)
|
||||
{
|
||||
if (request.equipmentNumbers().size() == 0)
|
||||
return false;
|
||||
const int equipmentNumber = request.equipmentNumbers().at(0);
|
||||
auto it = m_equipNo2ExerciseId.constFind(equipmentNumber);
|
||||
if (it == m_equipNo2ExerciseId.cend())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not send equipment message to training area - equipment number "
|
||||
<< equipmentNumber << " not known";
|
||||
return false;
|
||||
}
|
||||
ExerciseHandler *exH = exerciseHandlerForExerciseId(it.value());
|
||||
return exH->sendOcEquipmentMessage(request);
|
||||
}
|
||||
|
||||
ExerciseHandler *ExercisesHandler::exerciseHandlerForExerciseId(int exerciseId)
|
||||
{
|
||||
const auto itEH = m_exerciseHandler.find(exerciseId);
|
||||
if (itEH != m_exerciseHandler.end())
|
||||
return itEH.value();
|
||||
|
||||
DEBUG_LOG(m_logger) << "new ExerciseHandler for id " << exerciseId;
|
||||
auto exH = new ExerciseHandler(m_ddsHandler->ddsConnector(), exerciseId);
|
||||
bool result = exH->init();
|
||||
DEBUG_LOG(m_logger)<<"result init ="<<result;
|
||||
connect(exH, &ExerciseHandler::exerciseHandlerIdleTimeout,
|
||||
this, &ExercisesHandler::onExerciseHandlerIdleTimeout);
|
||||
m_exerciseHandler[exerciseId] = exH;
|
||||
return exH;
|
||||
}
|
||||
|
||||
void ExercisesHandler::onEquipmentExerciseMappingChanged(const ParticipantManagement::EquipmentExerciseMapping &data,
|
||||
DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onEquipmentExerciseMappingChanged";
|
||||
|
||||
for (auto it = m_equipNo2ExerciseId.begin(); it != m_equipNo2ExerciseId.end(); )
|
||||
{
|
||||
if (it.value() != data.exerciseId())
|
||||
++it;
|
||||
else
|
||||
it = m_equipNo2ExerciseId.erase(it);
|
||||
}
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
for (const ParticipantManagement::Equipment2ParticipantId &e2p : data.mapping())
|
||||
{
|
||||
m_equipNo2ExerciseId[e2p.equipmentNumber()] = data.exerciseId();
|
||||
QPair<int,int> exePart;
|
||||
exePart.first = data.exerciseId();
|
||||
exePart.second = e2p.participantId();
|
||||
m_participant2EquipNumber[exePart] = e2p.equipmentNumber();
|
||||
}
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ExercisesHandler::onEquipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, const DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onEquipmentMessageChanged";
|
||||
if (modType != DataModification::eAdded &&
|
||||
modType != DataModification::eModified)
|
||||
return;
|
||||
const int equipmentNumber = data.equipmentNumber();
|
||||
const auto it = m_equipNo2ExerciseId.constFind(equipmentNumber);
|
||||
if (it == m_equipNo2ExerciseId.constEnd())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Got EquipmentMessage from unknown participant with equipment number " << equipmentNumber;
|
||||
return;
|
||||
}
|
||||
emit messageFromTrainingArea(data);
|
||||
}
|
||||
|
||||
void ExercisesHandler::onExerciseHandlerIdleTimeout()
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"onExerciseHandlerIdleTimeout";
|
||||
ExerciseHandler *exH = qobject_cast<ExerciseHandler *>(sender());
|
||||
if (!exH)
|
||||
return;
|
||||
const int exerciseId = exH->exerciseId();
|
||||
auto it = m_exerciseHandler.find(exerciseId);
|
||||
if (it != m_exerciseHandler.end())
|
||||
{
|
||||
exH->deleteLater();
|
||||
m_exerciseHandler.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Messaging
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Get information about (O/C) participants to be able to send/receive messages for them
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-12-13
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <OcSituationServer/oss_dtc.h>
|
||||
#include <TrainingAreaBase/tab.hpp>
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
class ExerciseHandler;
|
||||
class ExercisesHandler final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExercisesHandler(const std::shared_ptr<DdsHandler> &ddsHandler);
|
||||
~ExercisesHandler();
|
||||
|
||||
bool init();
|
||||
bool sendEquipmentMessage(const TrainingAreaBase::SendEquipmentMessageRequest &request);
|
||||
bool sendOcEquipmentMessage(const OcSituationServer::SendEquipmentMessageRequest &request);
|
||||
int findEquipmentNumber(int participantId, int exerciseId);
|
||||
Q_SIGNALS:
|
||||
void messageFromTrainingArea(const TrainingAreaBase::EquipmentMessage &data);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onEquipmentExerciseMappingChanged(const ParticipantManagement::EquipmentExerciseMapping &data, DataModification modType);
|
||||
void onEquipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, const DataModification modType);
|
||||
void onExerciseHandlerIdleTimeout();
|
||||
private:
|
||||
ExerciseHandler *exerciseHandlerForExerciseId(int exerciseId);
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
QHash<int, ExerciseHandler *> m_exerciseHandler;
|
||||
// QHash< QPair<exerciseId,ParticipantId>, equipmentNumber>
|
||||
QHash<QPair<int,int>, int> m_participant2EquipNumber;
|
||||
QHash<int, int> m_equipNo2ExerciseId;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace Messaging
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
* Handler for message data request
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-10-12
|
||||
*/
|
||||
|
||||
#include "handler_operator_message.h"
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
HandlerOperatorMessage::HandlerOperatorMessage(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<ExercisesHandler> &exercisesHandler,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, CreateOperatorMessageRequestHandler(ddsHandler->fts())
|
||||
, ModifyOperatorMessageRequestHandler(ddsHandler->fts())
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_db(db)
|
||||
, m_exercisesHandler(exercisesHandler)
|
||||
, m_logger(getLogger("HandlerOperatorMessage"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool HandlerOperatorMessage::init()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Start HandlerOperatorMessage.";
|
||||
|
||||
// read data from db-table 'msg_message_data'
|
||||
// add to internal buffer
|
||||
auto cbMsgData = [this] (const Database::MsgMessageData &data)
|
||||
{
|
||||
if (data.isDeleted)
|
||||
return;
|
||||
m_dbOperatorMessageData.insert(data.id, data);
|
||||
m_ddsHandler->dts()->publish(toDdsData(data));
|
||||
};
|
||||
if (!m_db->select(cbMsgData)) // TODO (CE): nicht alle selektieren, nur die, die nicht gelöscht sind
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error reading data from database 'msg_message_data'!";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Signal von tabDtc verbinden ( void equipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, DataModification modType))
|
||||
// enableEquipmentMessage zum abbonieren der EquipmentMessages
|
||||
// Alle derzeit vorhandenen Messages auslesen (equipmentMessages()) und verarbeiten
|
||||
|
||||
connect(m_exercisesHandler.get(), &ExercisesHandler::messageFromTrainingArea,
|
||||
this, &HandlerOperatorMessage::onMesssageFromTrainingArea);
|
||||
|
||||
//OperatorManagement::Interface::Dtc
|
||||
m_opmDtc = OperatorManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector());
|
||||
// Operator Management to get Username from operator
|
||||
connect(m_opmDtc.get(), &OperatorManagement::Interface::Dtc::userChanged,
|
||||
this, &HandlerOperatorMessage::onOperatorChanged);
|
||||
m_opmDtc->enableUser();
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOperatorMessage::onCreateOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
|
||||
const CreateOperatorMessageRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onCreateOperatorMessageRequest" << request;
|
||||
auto ret = createOperatorMessageRequest(request);
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
m_ddsHandler->fts()->createOperatorMessageReply(cookie, ret);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject HandlerOperatorMessage::createOperatorMessageRequest(const CreateOperatorMessageRequest &request)
|
||||
{
|
||||
// 1. In DB eintragen
|
||||
// 2. publishen
|
||||
// 3. in interne Verwaltung eintragen
|
||||
// 4. mit ok antworten
|
||||
|
||||
Database::MsgMessageData newMsg;
|
||||
newMsg.timeStamp = m_ddsHandler->currentPartitionTime();
|
||||
newMsg.senderId = request.senderId();
|
||||
INFO_LOG(m_logger) << "newMsg.senderId=" << newMsg.senderId;
|
||||
newMsg.subject = QString::fromStdString(request.subject());
|
||||
newMsg.message = QString::fromStdString(request.message());
|
||||
newMsg.senderType = request.senderType();
|
||||
|
||||
INFO_LOG(m_logger) << "newMsg.senderType.underlying()=" << newMsg.senderType.underlying();
|
||||
newMsg.senderText = toAddressStr(newMsg.senderType, newMsg.senderId, request.exerciseId());
|
||||
newMsg.recipientType = request.recipientType();
|
||||
newMsg.exerciseId = request.exerciseId();
|
||||
|
||||
QString recipientText;
|
||||
for (int32_t i : request.recipientIds())
|
||||
{
|
||||
recipientText.append(toAddressStr(newMsg.recipientType, i, newMsg.exerciseId));
|
||||
recipientText.append(QString::fromStdString(" "));
|
||||
}
|
||||
newMsg.isRead = false;
|
||||
newMsg.isDeleted = false;
|
||||
|
||||
INFO_LOG(m_logger) << "newMsg.senderType=" << newMsg.senderType << " newMsg.receiverType=" << newMsg.recipientType;
|
||||
// Insert message for sender
|
||||
newMsg.recipientId = 0;
|
||||
newMsg.recipientText = recipientText;
|
||||
// Only Operator messages
|
||||
Core::FunctionReplyObject ret(newMsg.id);
|
||||
if (newMsg.senderType == Messaging::AddressType_def::type::Operator)
|
||||
ret = insertInDbAndPublish(newMsg);
|
||||
|
||||
const int correspondingOutboxMsgId = ret.id();
|
||||
|
||||
if (!ret.error() )
|
||||
{
|
||||
INFO_LOG(m_logger) << "insert message for each receiver";
|
||||
// Insert message for each receiver
|
||||
//newMsg.senderId = 0; WHY?
|
||||
//if (correspondingOutboxMsgId > 0) // messages received from TETRA dont have a corresponding outbox id
|
||||
newMsg.correspondingOutboxMessageId = correspondingOutboxMsgId; // can be also 0 - from TETRA
|
||||
|
||||
for (const auto recipientId : request.recipientIds())
|
||||
{
|
||||
newMsg.recipientId = recipientId;
|
||||
newMsg.recipientText = toAddressStr(newMsg.recipientType, newMsg.recipientId, newMsg.exerciseId);
|
||||
INFO_LOG(m_logger) << "recipientId: " << newMsg.recipientId;
|
||||
ret = insertInDbAndPublish(newMsg);
|
||||
if (ret.error())
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
|
||||
return ret;
|
||||
|
||||
} // end of onCreateOperatorMessageRequest()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOperatorMessage::onModifyOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
|
||||
const ModifyOperatorMessageRequest &request)
|
||||
{
|
||||
// 1. schauen ob es diese Message überhaupt gibt
|
||||
// 2. aktualisieren in DB
|
||||
// 3. interne Verwaltung aktualisieren
|
||||
// 4. neu publishen bzw. von dds löschen
|
||||
// 5. mit ok antworten
|
||||
|
||||
auto it = m_dbOperatorMessageData.find(request.id());
|
||||
if (it == m_dbOperatorMessageData.end())
|
||||
{
|
||||
const auto ret = Core::FunctionReplyObject(0, tr_lts("dds", "Could not find message with id %1")).arg(request.id());
|
||||
m_ddsHandler->fts()->modifyOperatorMessageReply(cookie, ret);
|
||||
return;
|
||||
}
|
||||
Database::MsgMessageData data = it.value();
|
||||
data.isDeleted = request.isDeleted();
|
||||
data.isSend = request.isSend();
|
||||
data.isRead = request.isRead();
|
||||
const auto ret = modifyDbAndPublish(data);
|
||||
|
||||
m_ddsHandler->fts()->modifyOperatorMessageReply(cookie, ret);
|
||||
} // end of onModifyOperatorMessageRequest()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
OperatorMessage HandlerOperatorMessage::toDdsData(const Database::MsgMessageData &dbData)
|
||||
{
|
||||
OperatorMessage ddsData;
|
||||
ddsData.id(dbData.id);
|
||||
ddsData.senderId(dbData.senderId);
|
||||
ddsData.recipientId(dbData.recipientId);
|
||||
ddsData.exerciseId(dbData.exerciseId);
|
||||
ddsData.subject(dbData.subject.toStdString());
|
||||
ddsData.message(dbData.message.toStdString());
|
||||
ddsData.recipientText(dbData.recipientText.toStdString());
|
||||
ddsData.senderText(dbData.senderText.toStdString());
|
||||
ddsData.isRead(dbData.isRead);
|
||||
ddsData.isSend(dbData.isSend);
|
||||
ddsData.isDeleted(dbData.isDeleted);
|
||||
ddsData.senderType(dbData.senderType);
|
||||
ddsData.recipientType(dbData.recipientType);
|
||||
ddsData.correspondingOutboxMessageId(dbData.correspondingOutboxMessageId); // can also be 0
|
||||
ddsData.timeStamp(dbData.timeStamp);
|
||||
return ddsData;
|
||||
} // end of toDdsData()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Insert in db and publish
|
||||
Core::FunctionReplyObject HandlerOperatorMessage::insertInDbAndPublish(Database::MsgMessageData newMsg)
|
||||
{
|
||||
// Length Check:
|
||||
if (newMsg.recipientType == Messaging::AddressType_def::type::ObserverController)
|
||||
{
|
||||
newMsg.subject = newMsg.subject.left(m_maxSubjectLength);
|
||||
newMsg.message = newMsg.message.left(m_maxOcContentLength);
|
||||
}
|
||||
if (newMsg.recipientType == Messaging::AddressType_def::type::Participant)
|
||||
{
|
||||
newMsg.subject = newMsg.subject.left(m_maxSubjectLength);
|
||||
newMsg.message.clear();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "newMsg.senderId = " << newMsg.senderId;
|
||||
if (!m_db->insert(newMsg))
|
||||
return Core::FunctionReplyObject(0, tr_lts("dds", "Error adding message to database"));
|
||||
|
||||
m_dbOperatorMessageData.insert(newMsg.id, newMsg);
|
||||
|
||||
if ((newMsg.recipientType == Messaging::AddressType_def::type::ObserverController)
|
||||
|| (newMsg.recipientType == Messaging::AddressType_def::type::Participant))
|
||||
{
|
||||
|
||||
int32_t equipmentNumber = m_exercisesHandler->findEquipmentNumber(newMsg.recipientId, newMsg.exerciseId);
|
||||
int32_t participantId = newMsg.recipientId;
|
||||
|
||||
INFO_LOG(m_logger) << "equipmentNumber: " << equipmentNumber << ", participantId: " << participantId << ", exerciseId: " << newMsg.exerciseId;
|
||||
|
||||
// Length Check:
|
||||
const auto subject = newMsg.subject.toStdString();
|
||||
const auto message = newMsg.message.toStdString();
|
||||
INFO_LOG(m_logger) << "Message to OC: subject =" << subject << " Message =" << message;
|
||||
|
||||
// only send to Tetra:
|
||||
if (newMsg.recipientId > 0)
|
||||
{
|
||||
int senderId = m_dbOperatorMessageData[newMsg.correspondingOutboxMessageId].senderId;
|
||||
AddressType senderType = m_dbOperatorMessageData[newMsg.correspondingOutboxMessageId].senderType;
|
||||
INFO_LOG(m_logger) << "SendEquipmentMessageRequest id =" << newMsg.id;
|
||||
INFO_LOG(m_logger) << " equipmentNumber=" << equipmentNumber
|
||||
<< " participantId=" << participantId
|
||||
<< " newMsg.id=" << newMsg.id
|
||||
<< " newMsg.senderId=" << senderId
|
||||
<< " newMsg.adressType=" << senderType
|
||||
<< " subject=" << subject
|
||||
<< " message=" << message;
|
||||
static int s_requestId = 1;
|
||||
if (newMsg.recipientType == Messaging::AddressType_def::type::ObserverController)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Send to OC senderId=" << newMsg.senderId << " sendertype: " << newMsg.senderType << " subject " << subject;
|
||||
m_exercisesHandler->sendOcEquipmentMessage({s_requestId++,
|
||||
{equipmentNumber},
|
||||
//newMsg.id,
|
||||
newMsg.senderId,
|
||||
newMsg.senderType,
|
||||
subject,
|
||||
message
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_exercisesHandler->sendEquipmentMessage({s_requestId++,
|
||||
{equipmentNumber},
|
||||
newMsg.id,
|
||||
senderId,
|
||||
subject,
|
||||
message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//m_ddsHandler->tabFtc()->sendEquipmentMessageRequest(...);
|
||||
//onsendEquipmentMessageReply implementieren und dort gelesen = true;
|
||||
}
|
||||
|
||||
m_ddsHandler->dts()->publish(toDdsData(newMsg));
|
||||
|
||||
INFO_LOG(m_logger) << "insertInDbAndPublish id=" << newMsg.id;
|
||||
if (newMsg.recipientType == Messaging::AddressType_def::type::ObserverController && newMsg.recipientId > 0)
|
||||
{
|
||||
INFO_LOG(m_logger) << "O/C-Message in Member-Variable kopieren: id = " << newMsg.id;
|
||||
}
|
||||
|
||||
return Core::FunctionReplyObject(newMsg.id);
|
||||
|
||||
} // end of insertInDbAndPublish()
|
||||
|
||||
// Modify db and publish
|
||||
Core::FunctionReplyObject HandlerOperatorMessage::modifyDbAndPublish(const Database::MsgMessageData &modMsg)
|
||||
{
|
||||
INFO_LOG(m_logger) << "modifyDbAndPublish" << " id=" << modMsg.id <<
|
||||
" isDeleted=" << modMsg.isDeleted <<
|
||||
" modMsg.isRead=" << modMsg.isRead <<
|
||||
" modMsg.isSend=" << modMsg.isSend <<
|
||||
" modMsg.sender=" << modMsg.senderId <<
|
||||
" modMsg.receiver=" << modMsg.recipientId;
|
||||
if (!m_db->update(modMsg))
|
||||
return Core::FunctionReplyObject(modMsg.id,
|
||||
tr_lts("dds", "Error updating message with id %1 to database")).arg(modMsg.id);
|
||||
|
||||
m_dbOperatorMessageData[modMsg.id] = modMsg;
|
||||
if (modMsg.isDeleted)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Remove LTS_OperatorMessage from DDS id=" << modMsg.id;
|
||||
m_ddsHandler->dts()->removeOperatorMessageByKey(modMsg.id);
|
||||
}
|
||||
else
|
||||
m_ddsHandler->dts()->publish(toDdsData(modMsg));
|
||||
|
||||
return Core::FunctionReplyObject(modMsg.id);
|
||||
} // end of modifyDbAndPublish()
|
||||
|
||||
// Receive from Tetra
|
||||
void HandlerOperatorMessage::onMesssageFromTrainingArea(const TrainingAreaBase::EquipmentMessage &data)
|
||||
{
|
||||
INFO_LOG(m_logger) << "************ onMesssageFromTrainingArea ********************";
|
||||
onEquipmentMessageChanged(data, DataModification::eAdded);
|
||||
}
|
||||
|
||||
// Receive from Tetra
|
||||
void HandlerOperatorMessage::onEquipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, const DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
CreateOperatorMessageRequest request;
|
||||
DEBUG_LOG(m_logger) << "onEquipmentMessageChanged: " << data;
|
||||
|
||||
request.senderType() = Messaging::AddressType_def::type::Participant;
|
||||
request.senderId(data.sender());
|
||||
DEBUG_LOG(m_logger) << "request.senderId = " << request.senderId();
|
||||
request.recipientType(Messaging::AddressType_def::type::Operator);
|
||||
request.recipientIds().push_back(data.receiver());
|
||||
request.subject() = data.subject();
|
||||
request.message() = data.text();
|
||||
|
||||
createOperatorMessageRequest(request);
|
||||
// Todo Fragen, ob die Meldung vom DDS geloescht werden soll.
|
||||
} // end of onEquipmentMessageChanged
|
||||
|
||||
void HandlerOperatorMessage::onOperatorChanged(const OperatorManagement::User &data)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "************** onOperatorChanged ";
|
||||
m_operatorMap.insert(data.id(), data.name());
|
||||
} // end of onOperatorChanged
|
||||
|
||||
QString HandlerOperatorMessage::toAddressStr(const AddressType addressType, const qint32 addressId, int exerciseId)
|
||||
{
|
||||
QString result;
|
||||
switch (addressType.underlying())
|
||||
{
|
||||
case AddressType::Operator:
|
||||
// nicht per Request sondern hier aus OPM holen
|
||||
result = QString::fromStdString(m_operatorMap.value(addressId, "Unknown Operator"));
|
||||
break;
|
||||
case AddressType::ObserverController:
|
||||
{
|
||||
int equipNumber = m_exercisesHandler->findEquipmentNumber(addressId, exerciseId);
|
||||
if (equipNumber > 0)
|
||||
result += QStringLiteral(" - ") + QString::number(equipNumber);
|
||||
break;
|
||||
}
|
||||
case AddressType::Participant:
|
||||
result = QLatin1String("Participant:") + QString::number(addressId);
|
||||
break;
|
||||
default:
|
||||
result = QString::fromStdString("No valid addressType:");
|
||||
QString numberStr ;
|
||||
numberStr.setNum(addressType.underlying());
|
||||
result.append(numberStr);
|
||||
}
|
||||
return result;
|
||||
} // end of toAddressStr
|
||||
|
||||
} // namespace Messaging
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Handler for table-io message data request
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-10-12
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include "dds_handler.h"
|
||||
#include "exercises_handler.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <Messaging/msg_fts.h>
|
||||
#include <Messaging/msg_db.h>
|
||||
|
||||
#include <TrainingAreaBase/tab.hpp>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
class HandlerOperatorMessage final
|
||||
: public QObject
|
||||
, protected Interface::Fts::CreateOperatorMessageRequestHandler
|
||||
, protected Interface::Fts::ModifyOperatorMessageRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerOperatorMessage(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<ExercisesHandler> &exercisesHandler,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
bool init();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onMesssageFromTrainingArea(const TrainingAreaBase::EquipmentMessage &data);
|
||||
void onEquipmentMessageChanged(const TrainingAreaBase::EquipmentMessage &data, const DataModification modType);
|
||||
void onOperatorChanged(const OperatorManagement::User &data);
|
||||
|
||||
private: // methods
|
||||
void onCreateOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
|
||||
const CreateOperatorMessageRequest &request) override;
|
||||
Core::FunctionReplyObject createOperatorMessageRequest(const CreateOperatorMessageRequest &request);
|
||||
void onModifyOperatorMessageRequest(const rti::core::SampleIdentity &cookie,
|
||||
const ModifyOperatorMessageRequest &request) override;
|
||||
|
||||
// convert methodes
|
||||
static OperatorMessage toDdsData(const Database::MsgMessageData &dbData); // db -> dds
|
||||
QString toAddressStr(const AddressType addressType, const qint32 addressId, int exerciseId);
|
||||
|
||||
Core::FunctionReplyObject insertInDbAndPublish(Database::MsgMessageData newMsg);
|
||||
Core::FunctionReplyObject modifyDbAndPublish(const Database::MsgMessageData &modMsg);
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<DatabaseInterface> m_db;
|
||||
std::shared_ptr<ExercisesHandler> m_exercisesHandler;
|
||||
QMap<int, Database::MsgMessageData> m_dbOperatorMessageData;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
|
||||
//std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
QMap<int, std::string> m_operatorMap;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
static const unsigned int m_maxSubjectLength = 80;
|
||||
static const unsigned int m_maxOcContentLength = 1024;
|
||||
};
|
||||
} // namespace Messaging
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: Messaging
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.MSG=INFO
|
||||
#log4j.logger.MSG.DdsHandler=INFO
|
||||
#log4j.logger.MSG.ExerciseHandler=INFO
|
||||
#log4j.logger.MSG.ExercisesHandler=INFO
|
||||
#log4j.logger.MSG.HandlerOperatorMessage=INFO
|
||||
|
||||
# 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:
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "MSG.";
|
||||
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 Messaging
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for Messaging
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "msg_export.h"
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
MSG_COMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace Messaging
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* main for Messaging
|
||||
* $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("MSG", options.exerciseId());
|
||||
|
||||
Messaging::Settings::setIniFile(options.iniFile());
|
||||
|
||||
int iRet = -3;
|
||||
{
|
||||
std::unique_ptr<Messaging::MainHandler> mainHandler(new Messaging::MainHandler);
|
||||
|
||||
if (!mainHandler->init(options.domainId()))
|
||||
return iRet;
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
iRet = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* MainHandler for MessageDataManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-09-21
|
||||
*/
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
#include <ngldb/db_service_handler.h>
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
|
||||
MainHandler::MainHandler()
|
||||
: m_logger(getLogger("MainHandler"))
|
||||
{
|
||||
INFO_LOG(m_logger) << "MainHandler::MainHandler";
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
INFO_LOG(m_logger) << "MainHandler::~MainHandler";
|
||||
m_handlerOperatorMessage = nullptr;
|
||||
m_exercisesHandler = nullptr;
|
||||
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 HandlerExercises. ";
|
||||
m_exercisesHandler = std::make_shared<ExercisesHandler>(m_ddsHandler);
|
||||
if (!m_exercisesHandler->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "create HandlerExercise failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << "m_exercisesHandler="<<m_exercisesHandler;
|
||||
|
||||
|
||||
|
||||
// create HandlerCreate
|
||||
INFO_LOG(m_logger) << "create HandlerCreate. ";
|
||||
m_handlerOperatorMessage = std::make_shared<HandlerOperatorMessage>(m_ddsHandler, m_dbHandler->db(), m_exercisesHandler);
|
||||
if (!m_handlerOperatorMessage->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "create HandlerMarkAsDelete failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "HandlerCreate initialized. ";
|
||||
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
|
||||
//m_ddsHandler->enableEquipmentMessage();
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
} // namespace Messaging
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* MainHandler for Messaging
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-09-21
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "handler_operator_message.h"
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "exercises_handler.h"
|
||||
#include "logger.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace NGLDB
|
||||
{
|
||||
template <typename DB> class DbServiceHandler;
|
||||
}
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
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<ExercisesHandler> m_exercisesHandler; ///<Messages from OC
|
||||
std::shared_ptr<HandlerOperatorMessage> m_handlerOperatorMessage; ///< Messages between Operators / O/C
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
} // namespace MessagingDataManagement
|
||||
Executable
+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 MSG_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define MSG_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCMSGCOMMON_LIB)
|
||||
# define MSG_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define MSG_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MSG_CLIENT_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define MSG_CLIENT_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCMSGCLIENT_LIB)
|
||||
# define MSG_CLIENT_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define MSG_CLIENT_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MSG_SERVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define MSG_SERVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCMSGSERVER_LIB)
|
||||
# define MSG_SERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define MSG_SERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="Messaging" abbreviation="MSG" procNames="Messaging" exerciseDependency="Global" groups="Core" prio="3">
|
||||
<rcs>
|
||||
<Id Id="$Id$"/>
|
||||
<HeadURL HeadURL="$HeadURL$"/>
|
||||
<Author Author="$Author$"/>
|
||||
</rcs>
|
||||
<operatorRights offset="21">
|
||||
<guiPlugin name="Messaging" offset="1">
|
||||
<operatorRightGroup name="Messages" description="Edit and Send Operator and OC Messages">
|
||||
<operatorRight right="MessagesShow" value="1" description="Show (own) Messages"/>
|
||||
<operatorRight right="MessagesSend" value="2" description="Edit and Send Operator Messages"/>
|
||||
<operatorRight right="MessagesSendOc" value="3" description="Send Messages to O/C"/>
|
||||
</operatorRightGroup>
|
||||
</guiPlugin>
|
||||
</operatorRights>
|
||||
<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="msg_message_operator_data">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="time_stamp" datatype="bigint"/>
|
||||
<column name="sender_id" datatype="integer" default="1"/>
|
||||
<column name="recipient_id" datatype="integer"/>
|
||||
<column name="exercise_id" datatype="integer"/>
|
||||
<column name="is_read" datatype="boolean"/>
|
||||
<column name="is_send" datatype="boolean"/>
|
||||
<column name="is_deleted" datatype="boolean"/>
|
||||
<column name="subject" datatype="text"/>
|
||||
<column name="message" datatype="text"/>
|
||||
<column name="sender_text" datatype="text"/>
|
||||
<column name="recipient_text" datatype="text"/>
|
||||
<column name="recipient_type" datatype="integer" isForeignKey="1"/>
|
||||
<column name="sender_type" datatype="integer" isForeignKey="1"/>
|
||||
<column name="corresponding_outbox_message_id" datatype="integer" default="0"/>
|
||||
<constraint name="UQ_msg_message_data_id" type="unique">
|
||||
<column name="id"/>
|
||||
</constraint>
|
||||
<constraint name="IDX_msg_message_operator_is_deleted" type="index">
|
||||
<column name="is_deleted"/>
|
||||
</constraint>
|
||||
<foreignKey name="FK_msg_message_operator_data_address_type_recv">
|
||||
<source table="msg_message_operator_data" column="recipient_type"/>
|
||||
<destination table="address_type" column="id"/>
|
||||
</foreignKey>
|
||||
<foreignKey name="FK_msg_message_operator_data_address_type_send">
|
||||
<source table="msg_message_operator_data" column="sender_type"/>
|
||||
<destination table="address_type" column="id"/>
|
||||
</foreignKey>
|
||||
</table>
|
||||
</tables>
|
||||
<views/>
|
||||
<dbServiceStructs>
|
||||
<serviceStruct name="MsgMessageData" table="msg_message_operator_data"/>
|
||||
<table name="msg_message_operator_data"/>
|
||||
</dbServiceStructs>
|
||||
<topicTypes>
|
||||
<topicType name="CreateOperatorMessageRequest">
|
||||
<column name="recipientIds" idlType="sequence<long>" comment="Dependent on recipientType: - OperatorId, - ParticipantId"/>
|
||||
<column name="exerciseId" idlType="long"/>
|
||||
<column name="senderId" idlType="long" comment="Dependent on senderType: - OperatorId, - ParticipantId (or EqId?)"/>
|
||||
<column name="subject" idlType="string"/>
|
||||
<column name="message" idlType="string" comment="Shall be empty if Receiver is Non-O/C Participant. Not optional though."/>
|
||||
<column name="senderType" idlType="AddressType"/>
|
||||
<column name="recipientType" idlType="AddressType"/>
|
||||
</topicType>
|
||||
<topicType name="ModifyOperatorMessageRequest">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="isRead" idlType="boolean"/>
|
||||
<column name="isSend" idlType="boolean"/>
|
||||
<column name="isDeleted" idlType="boolean"/>
|
||||
</topicType>
|
||||
<topicType name="OperatorMessage" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="senderId" idlType="long"/>
|
||||
<column name="recipientId" idlType="long"/>
|
||||
<column name="exerciseId" idlType="long"/>
|
||||
<column name="subject" idlType="string"/>
|
||||
<column name="message" idlType="string"/>
|
||||
<column name="isRead" idlType="boolean"/>
|
||||
<column name="isSend" idlType="boolean"/>
|
||||
<column name="isDeleted" idlType="boolean"/>
|
||||
<column name="senderText" idlType="string"/>
|
||||
<column name="recipientText" idlType="string"/>
|
||||
<column name="senderType" idlType="AddressType"/>
|
||||
<column name="recipientType" idlType="AddressType"/>
|
||||
<column name="correspondingOutboxMessageId" idlType="long"/>
|
||||
<column name="timeStamp" idlType="long long"/>
|
||||
</topicType>
|
||||
</topicTypes>
|
||||
<functionTopics>
|
||||
<functionTopic name="ModifyOperatorMessage" requestTopicType="ModifyOperatorMessageRequest" replyTopicType="Core::FunctionReply" requestTopicName="ModifyOperatorMessageRequest" replyTopicName="ModifyOperatorMessageReply" routeInReplay="0"/>
|
||||
<functionTopic name="CreateOperatorMessage" requestTopicType="CreateOperatorMessageRequest" replyTopicType="Core::FunctionReply" requestTopicName="CreateOperatorMessageRequest" replyTopicName="CreateOperatorMessageReply" routeInReplay="0"/>
|
||||
</functionTopics>
|
||||
<enumerations>
|
||||
<enumeration name="AddressType" table="address_type">
|
||||
<attribute key="Operator" value="1"/>
|
||||
<attribute key="ObserverController" value="2"/>
|
||||
<attribute key="Participant" value="3"/>
|
||||
</enumeration>
|
||||
</enumerations>
|
||||
</service>
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Settings for Messaging
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace Messaging
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Settings for Messaging
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace Messaging
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
}
|
||||
|
||||
} // namespace Messaging
|
||||
Reference in new issue
Block a user