Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+201
@@ -0,0 +1,201 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
INCLUDE(MacroRTIDDSGen)
|
||||
INCLUDE(MacroCodeGenIdl)
|
||||
|
||||
SET(xml_FILE srp_service.xml)
|
||||
|
||||
#
|
||||
# --- Library svcSrpCommon --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_common
|
||||
srp_export.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
# Generate srp_enums.idl / srp.idl
|
||||
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
|
||||
# Generate srp_db_impl.cpp/.h, srp_db.h
|
||||
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
|
||||
|
||||
# Generate *.cpp/*.hpp from idl
|
||||
RTIDDSGEN(SRCS_common srp_enums.idl)
|
||||
RTIDDSGEN(SRCS_common srp.idl)
|
||||
|
||||
# Generate srp_dt[s,c]_types.h, srp_ft[s,c]_types.h
|
||||
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
|
||||
# generate srp_[d|f]tc.h
|
||||
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
|
||||
|
||||
# SV needed for topic type plugin
|
||||
NGL_ADD_LIBRARY(WS AAR SV svcSrpCommon SHARED ${SRCS_common})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcSrpCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(svcSrpCommon
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
ngldb
|
||||
ddscore
|
||||
NGLLogger
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcSrpCommon)
|
||||
|
||||
#
|
||||
# --- Library svcSrpClient --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_client
|
||||
srp_export.h
|
||||
)
|
||||
# generate srp_ftc_impl.[cpp|h]
|
||||
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(WS svcSrpClient SHARED ${SRCS_client})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcSrpClient
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcSrpClient
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
PUBLIC
|
||||
svcSrpCommon
|
||||
ddsftc
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcSrpClient)
|
||||
|
||||
#
|
||||
# --- Library svcSrpServer --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_server
|
||||
srp_export.h
|
||||
)
|
||||
# generate srp_[d|f]ts.h, srp_[d|f]ts_impl.[cpp|h]
|
||||
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS svcSrpServer SHARED ${SRCS_server})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcSrpServer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcSrpServer
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
ddsfts
|
||||
PUBLIC
|
||||
svcSrpCommon
|
||||
ngldb
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcSrpServer)
|
||||
|
||||
#
|
||||
# --- Topic Type Plugin --------------------------------------------------------------
|
||||
#
|
||||
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
|
||||
|
||||
#
|
||||
# --- Executable svcSituationReplay (sSrp) -------------------------------------------------
|
||||
#
|
||||
SET(SRCS_exe
|
||||
db_reader.cpp
|
||||
db_reader.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
handler_situation_replay.cpp
|
||||
handler_situation_replay.h
|
||||
main.cpp
|
||||
main_handler.cpp
|
||||
main_handler.h
|
||||
object_situation_replay.cpp
|
||||
object_situation_replay.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
${xml_FILE}
|
||||
)
|
||||
|
||||
# Generate srp.sql, srp.xml
|
||||
CODEGEN_SQL(SRCS_exe ${xml_FILE})
|
||||
|
||||
NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
NGL_ADD_EXECUTABLE(WS AAR SV svcSituationReplay ${SRCS_exe})
|
||||
NGL_TARGET_LINK_LIBRARIES(svcSituationReplay
|
||||
rscCommon
|
||||
Qt5::Core
|
||||
svcCoreClient
|
||||
svcSrpCommon
|
||||
svcSrpServer
|
||||
ddsconnector
|
||||
nglsettings
|
||||
ProjectConfig
|
||||
LtsCommandLineParser
|
||||
NGLLogger
|
||||
nglcoreapplication
|
||||
LtsPluginLoader
|
||||
ngltools
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(svcSituationReplay)
|
||||
NGL_INSTALL(WS FILES log4cxx_srp.props DESTINATION bin)
|
||||
|
||||
# svcSituationReplaySqlite
|
||||
SET(SRCS_sqlite
|
||||
db_reader.cpp
|
||||
db_reader.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
handler_situation_replay_sqlite.cpp
|
||||
handler_situation_replay_sqlite.h
|
||||
main_handler_sqlite.cpp
|
||||
main_handler_sqlite.h
|
||||
object_situation_replay.cpp
|
||||
object_situation_replay.h
|
||||
static_publisher.cpp
|
||||
static_publisher.h
|
||||
${xml_FILE}
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS SituationReplaySqlite SHARED ${SRCS_sqlite})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(SituationReplaySqlite
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
${CMAKE_CURRENT_BINARY_DIR}/..
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(SituationReplaySqlite
|
||||
ddsconnector
|
||||
LtsPluginLoader
|
||||
LtsScriptTimeline
|
||||
NGLLogger
|
||||
ngltools
|
||||
Qt5::Core
|
||||
Qt5::Sql
|
||||
rscCommon
|
||||
svcCoreClient
|
||||
svcSrpCommon
|
||||
svcSrpServer
|
||||
|
||||
svcAsmServer
|
||||
svcExmServer
|
||||
svcFlmServer
|
||||
svcIsmServer
|
||||
svcPdmServer
|
||||
svcPpmServer
|
||||
)
|
||||
|
||||
# Uncomment if necessary
|
||||
#ADD_SUBDIRECTORY(UnitTests)
|
||||
ADD_SUBDIRECTORY(ModuleTests)
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(SRCS_DT_TEST
|
||||
srp_dt_tests.cpp
|
||||
)
|
||||
SET(HDRS_DT_TEST
|
||||
srp_dt_tests.h
|
||||
)
|
||||
|
||||
SET(SRCS_FT_TEST
|
||||
srp_ft_tests.cpp
|
||||
)
|
||||
SET(HDRS_FT_TEST
|
||||
srp_ft_tests.h
|
||||
)
|
||||
|
||||
IF(BUILD_TESTING)
|
||||
IF(TARGET svcSrpClient)
|
||||
|
||||
# Testing DataTopic Functionality (DTC)
|
||||
ADD_EXECUTABLE(srpDtTests ${SRCS_DT_TEST} ${HDRS_DT_TEST})
|
||||
TARGET_LINK_LIBRARIES(srpDtTests
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
RTI::nddscpp2
|
||||
svcSrpClient
|
||||
LtsCommandLineParser
|
||||
ddsconnector
|
||||
nglcoreapplication
|
||||
)
|
||||
|
||||
# Testing FunctionTopic Functionality (FTC)
|
||||
ADD_EXECUTABLE(srpFtTests ${SRCS_FT_TEST} ${HDRS_FT_TEST})
|
||||
TARGET_LINK_LIBRARIES(srpFtTests
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
RTI::nddscpp2
|
||||
svcSrpClient
|
||||
LtsCommandLineParser
|
||||
ddsconnector
|
||||
nglcoreapplication
|
||||
)
|
||||
IF(NOT BUILD_RPM)
|
||||
NGL_INSTALL(AAR SV TARGETS srpDtTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV TARGETS srpFtTests DESTINATION bin/test)
|
||||
NGL_INSTALL(AAR SV FILES ../log4cxx_srp.props DESTINATION bin/test)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* SRP Data Topic test executable
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-11
|
||||
*/
|
||||
|
||||
#include "srp_dt_tests.h"
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include <QTimer>
|
||||
|
||||
#include <SituationReplay/srp_dtc.h>
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
namespace SituationReplay
|
||||
{
|
||||
SrpDtTests::SrpDtTests(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_replayPartitionId(0)
|
||||
, m_situationReplayId(0)
|
||||
, m_bTestsSuccessful(true)
|
||||
, m_logger(getLogger("DtTest"))
|
||||
{
|
||||
qRegisterMetaType<Core::FunctionReply>("Core::FunctionReply");
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
SrpDtTests::~SrpDtTests()
|
||||
{}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
bool SrpDtTests::init(int domainId, int replayPartitionId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "init begin";
|
||||
m_replayPartitionId = replayPartitionId;
|
||||
|
||||
// initialize DDS
|
||||
m_ddsConnector.reset(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::Replay, replayPartitionId));
|
||||
if (!m_ddsConnector->init())
|
||||
return false;
|
||||
|
||||
// Subscribe on replayPartition - default = true in this DdsSubscriber
|
||||
|
||||
// DdsInterface Subscriber
|
||||
m_ddsConnector->initSubscriber();
|
||||
|
||||
// DdsInterface Publisher
|
||||
//m_ddsConnector->setPublisher(new Publisher(domainId, m_ddsConnector->getPartition(), m_ddsConnector->getDomainParticipant()));
|
||||
|
||||
DEBUG_LOG(m_logger) << "Create dtc";
|
||||
m_dtc = SituationReplay::Interface::Dtc::create(m_ddsConnector);
|
||||
DEBUG_LOG(m_logger) << "Init dtc";
|
||||
bool bRet = m_dtc->enableAll();
|
||||
DEBUG_LOG(m_logger) << "init end - bRet = " << bRet;
|
||||
|
||||
connect(m_dtc.get(), &SituationReplay::Interface::Dtc::sitReplayChanged,
|
||||
this, &SrpDtTests::onReceiveSituationReplayData);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void SrpDtTests::startTest()
|
||||
{
|
||||
INFO_LOG(m_logger) << "startTest";
|
||||
QTimer::singleShot(1000, this, &SrpDtTests::tryGetAllSituationReplays);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void SrpDtTests::tryGetAllSituationReplays()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to get all situationReplays";
|
||||
const QMap<qint32, SituationReplay::SitReplay> map = m_dtc->sitReplays();
|
||||
if (map.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error requesting all situation replay data";
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(m_logger) << "Amout of existing situation replays = " << map.size();
|
||||
m_situationReplayId = map.firstKey();
|
||||
for(auto it = map.begin(); it != map.end(); ++it)
|
||||
INFO_LOG(m_logger) << "situationReplay(" << it.key() << ") : " << it.value().replayPartitionId() ;
|
||||
}
|
||||
|
||||
QTimer::singleShot(10, this, &SrpDtTests::tryGetSituationReplay);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void SrpDtTests::tryGetSituationReplay()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying get itemData for situationReplay " << m_situationReplayId;
|
||||
SituationReplay::SitReplay data = m_dtc->sitReplay(m_situationReplayId);
|
||||
|
||||
if (data.id() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error receiving data for situation replay " << m_situationReplayId;
|
||||
failExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(m_logger) << "## SitReplay(" << data.id() << "), replayPartition: " << data.replayPartitionId()
|
||||
<< ", on exercise " << data.exerciseId();
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void SrpDtTests::onReceiveSituationReplayData(const SituationReplay::SitReplay &data)
|
||||
{
|
||||
if (m_situationReplayId == data.id())
|
||||
INFO_LOG(m_logger) << "##################### Data for id = " << data.id() << " received";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void SrpDtTests::failExit()
|
||||
{
|
||||
m_bTestsSuccessful = false;
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser()
|
||||
: LtsCommandLineParser()
|
||||
{
|
||||
addOption( { QStringList() << QLatin1String("p") << QLatin1String("replay-partition-id")
|
||||
, QLatin1String("ReplayPartitionId (required).")
|
||||
, QLatin1String("> 0")
|
||||
, QLatin1String("1")
|
||||
} );
|
||||
|
||||
addHelpOption();
|
||||
}
|
||||
|
||||
int replayPartitionId() const { return isSet(QLatin1String("p")) ? value(QLatin1String("p")).toInt() : -1; }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("SRP", "log4cxx_srp.props");
|
||||
|
||||
int iRet = -1;
|
||||
CmdLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
if (options.replayPartitionId() <= 0)
|
||||
{
|
||||
ERROR_LOG(app.baseLogger()) << "Required parameter p: (replay) partitionId ";
|
||||
options.showHelp();
|
||||
return -2;
|
||||
}
|
||||
|
||||
std::unique_ptr<SituationReplay::SrpDtTests> srpDtTests(new SituationReplay::SrpDtTests);
|
||||
|
||||
if(!srpDtTests->init(options.domainId(), options.replayPartitionId()))
|
||||
return iRet;
|
||||
|
||||
QTimer::singleShot(0, srpDtTests.get(), &SituationReplay::SrpDtTests::startTest);
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
app.exec();
|
||||
iRet = srpDtTests->testsSuccessful() ? 0 : 1;
|
||||
fprintf(stderr, "%d\n", iRet);
|
||||
|
||||
DEBUG_LOG(app.baseLogger()) << "** TEST result = " << iRet;
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
|
||||
return iRet;
|
||||
}
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* SRP Data Topic test executable
|
||||
*
|
||||
* ModuleTests to get data from Service SituationReplay
|
||||
* -> getAll()
|
||||
* -> getItem()
|
||||
* ---------------------------------------------------
|
||||
* Client DTC is implemented
|
||||
*
|
||||
* => (!) Preconditon:
|
||||
* - Service sExeMgmt running
|
||||
*
|
||||
* -------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-11
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SituationReplay/srp_dtc.h>
|
||||
#include <SituationReplay/srp_dtc_types.h>
|
||||
#include <SituationReplay/logger.h>
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <DDS/DDSConnector/publisher.h>
|
||||
#include <DDS/DDSConnector/subscriber.h>
|
||||
|
||||
//#include <Common/ProjectConfig/project_defines.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class SrpDtTests : public QObject
|
||||
{
|
||||
using Publisher = DDSConnector::Publisher;
|
||||
using Subscriber = DDSConnector::Subscriber;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SrpDtTests(QObject *parent = nullptr);
|
||||
~SrpDtTests();
|
||||
|
||||
bool init(int domainId, int exerciseId);
|
||||
bool testsSuccessful() const { return m_bTestsSuccessful; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void startTest();
|
||||
protected Q_SLOTS:
|
||||
void tryGetAllSituationReplays();
|
||||
void tryGetSituationReplay();
|
||||
void onReceiveSituationReplayData(const SitReplay &data);
|
||||
protected:
|
||||
void failExit();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<SituationReplay::Interface::Dtc> m_dtc;
|
||||
qint32 m_replayPartitionId;
|
||||
qint32 m_situationReplayId;
|
||||
bool m_bTestsSuccessful;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // namespace SituationReplay
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* SRP Function Topic test executable
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-14
|
||||
*/
|
||||
|
||||
#include "srp_ft_tests.h"
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include <QTimer>
|
||||
|
||||
#include <SituationReplay/srp_ftc.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
SrpFtTests::SrpFtTests(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_replayPartitionId(0)
|
||||
, m_testId(All)
|
||||
, m_bTestsSuccessful(true)
|
||||
, m_logger(getLogger("FtTest"))
|
||||
{
|
||||
qRegisterMetaType<Core::FunctionReply>("Core::FunctionReply");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
SrpFtTests::~SrpFtTests()
|
||||
{}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool SrpFtTests::init(int domainId, TestId testId, int replayPartitionId, int srpId)
|
||||
{
|
||||
INFO_LOG(m_logger) << "init begin";
|
||||
|
||||
m_testId = testId;
|
||||
m_replayPartitionId = replayPartitionId;
|
||||
|
||||
if (m_testId > 0)
|
||||
m_situationReplayId = srpId;
|
||||
|
||||
// initialize DDS
|
||||
m_ddsConnector.reset(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::Replay, m_replayPartitionId));
|
||||
if (!m_ddsConnector->init())
|
||||
return false;
|
||||
|
||||
|
||||
// Publish/Subscribe on replayPartition
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
DEBUG_LOG(m_logger) << "create ftc";
|
||||
m_ftc = SituationReplay::Interface::Ftc::create(m_ddsConnector);
|
||||
DEBUG_LOG(m_logger) << "init ftc";
|
||||
bool bRet = m_ftc->enableAll();
|
||||
DEBUG_LOG(m_logger) << "init end - bRet = " << bRet;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::startTest()
|
||||
{
|
||||
INFO_LOG(m_logger) << "startTest";
|
||||
|
||||
if (m_testId <= TryStart)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryStart);
|
||||
else if (m_testId == TryNotAllowedChange)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryNotAllowedChange);
|
||||
else if (m_testId == TryChangePaused)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryChangePaused);
|
||||
else if (m_testId == TryChangeResumed)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryChangeResumed);
|
||||
else if (m_testId == TryStop)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryStop);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::tryStart()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send startReplay";
|
||||
m_currentTestId = TryStart;
|
||||
|
||||
qint64 beginTime = 1468401389668;
|
||||
qint64 endTime = 1468401659954;
|
||||
double pace = 2.0;
|
||||
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(0);
|
||||
req.replayPartitionId(m_replayPartitionId);
|
||||
req.state(SrpState::Started);
|
||||
req.beginTime(beginTime);
|
||||
req.endTime(endTime); // infinite
|
||||
req.pace(pace);
|
||||
|
||||
if (!m_ftc->changeReplayStateRequest(req, this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error starting replay for srp " << m_replayPartitionId;
|
||||
failExit();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::tryNotAllowedChange()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send changeReplayState (start) => should fail (not possible with this method)";
|
||||
m_currentTestId = TryNotAllowedChange;
|
||||
switchToState(SituationReplay::SrpState::Started);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::tryChangePaused()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send changeReplayState (Paused)";
|
||||
m_currentTestId = TryChangePaused;
|
||||
switchToState(SituationReplay::SrpState::Paused);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::tryChangeResumed()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send changeReplayState (Resumed)";
|
||||
m_currentTestId = TryChangeResumed;
|
||||
switchToState(SituationReplay::SrpState::Resumed);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::tryStop()
|
||||
{
|
||||
INFO_LOG(m_logger) << "trying to send stopReplay";
|
||||
m_currentTestId = TryStop;
|
||||
switchToState(SituationReplay::SrpState::Stopped);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::startReplayReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got startReplayReply with id " << replyObject.id();
|
||||
m_situationReplayId = replyObject.id();
|
||||
if (m_testId == 0 && !replyObject.error())
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryNotAllowedChange);
|
||||
else
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::changeReplayStateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got changeReplayStateReply with id " << replyObject.id();
|
||||
if (replyObject.error())
|
||||
INFO_LOG(m_logger) << ", string: " << replyObject.translated();
|
||||
if (m_testId == 0 && !replyObject.error())
|
||||
{
|
||||
if (m_currentTestId == TryNotAllowedChange)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryChangePaused);
|
||||
else if (m_currentTestId == TryChangePaused)
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryChangeResumed);
|
||||
else
|
||||
QTimer::singleShot(0, this, &SrpFtTests::tryStop);
|
||||
}
|
||||
else
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::stopReplayReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Got stopReplayReply with id " << replyObject.id() ;
|
||||
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::onChangeReplayStateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
switch (m_currentTestId)
|
||||
{
|
||||
case TryStart:
|
||||
startReplayReply(replyObject);
|
||||
break;
|
||||
case TryNotAllowedChange:
|
||||
case TryChangePaused:
|
||||
case TryChangeResumed:
|
||||
changeReplayStateReply(replyObject);
|
||||
break;
|
||||
case TryStop:
|
||||
stopReplayReply(replyObject);
|
||||
break;
|
||||
case All:
|
||||
changeReplayStateReply(replyObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
void SrpFtTests::failExit()
|
||||
{
|
||||
m_bTestsSuccessful = false;
|
||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void SrpFtTests::switchToState(SrpState state)
|
||||
{
|
||||
ChangeReplayStateRequest req;
|
||||
req.id(m_situationReplayId);
|
||||
req.replayPartitionId(m_replayPartitionId);
|
||||
req.state(state);
|
||||
|
||||
if (!m_ftc->changeReplayStateRequest(req, this))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error changing replay state for srp " << m_situationReplayId << "(" << m_replayPartitionId << ")";
|
||||
failExit();
|
||||
}
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser()
|
||||
: LtsCommandLineParser()
|
||||
{
|
||||
addOption( { QStringList() << QLatin1String("t") << QLatin1String("testId")
|
||||
, QLatin1String("TestId.")
|
||||
, QLatin1String("Default: 0 (all tests)")
|
||||
, QLatin1String("0")
|
||||
} );
|
||||
|
||||
addOption( { QStringList() << QLatin1String("p") << QLatin1String("replayPartitionId")
|
||||
, QLatin1String("ReplayPartitionId.")
|
||||
, QLatin1String("required")
|
||||
, QLatin1String("0")
|
||||
} );
|
||||
|
||||
addOption( { QStringList() << QLatin1String("r") << QLatin1String("situationReplayId")
|
||||
, QLatin1String("SituationReplayId.")
|
||||
, QLatin1String("optional")
|
||||
, QLatin1String("0")
|
||||
} );
|
||||
|
||||
addHelpOption();
|
||||
}
|
||||
|
||||
int testId() const { return isSet(QLatin1String("t")) ? value(QLatin1String("t")).toInt() : -1; }
|
||||
int replayPartitionId() const { return isSet(QLatin1String("p")) ? value(QLatin1String("p")).toInt() : -1; }
|
||||
int situationReplayId() const { return isSet(QLatin1String("r")) ? value(QLatin1String("r")).toInt() : -1; }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("SRP", "log4cxx_srp.props");
|
||||
|
||||
CmdLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
if (options.exerciseId() <= 0 || options.replayPartitionId() <= 0)
|
||||
{
|
||||
ERROR_LOG(app.baseLogger()) << "Required parameter: exerciseId & replayPartitionId ";
|
||||
options.showHelp();
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (options.testId() > 0 && options.situationReplayId() <= 0)
|
||||
{
|
||||
ERROR_LOG(app.baseLogger()) << "Required parameter for single test: situationReplayId ";
|
||||
options.showHelp();
|
||||
return -2;
|
||||
}
|
||||
|
||||
std::unique_ptr<SituationReplay::SrpFtTests> SrpFtTests(new SituationReplay::SrpFtTests);
|
||||
|
||||
int iRet = -1;
|
||||
if(!SrpFtTests->init(options.domainId(), SituationReplay::SrpFtTests::TestId(options.testId()),
|
||||
options.replayPartitionId(), options.situationReplayId()))
|
||||
return iRet;
|
||||
|
||||
QTimer::singleShot(0, SrpFtTests.get(), &SituationReplay::SrpFtTests::startTest);
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
app.exec();
|
||||
|
||||
iRet = SrpFtTests->testsSuccessful() ? 0 : 1;
|
||||
fprintf(stderr, "%d\n", iRet);
|
||||
|
||||
DEBUG_LOG(app.baseLogger()) << "** TEST result = " << iRet;
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
|
||||
return iRet;
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* SRP Function Topic test executable
|
||||
*
|
||||
* ModuleTests for create/modify/remove exercise
|
||||
* ---------------------------------------------------
|
||||
* Client FTC is implemented
|
||||
*
|
||||
* => (!) Preconditon:
|
||||
* - Service sSrp running
|
||||
*
|
||||
* -------------------------------------------------
|
||||
*
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-14
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SituationReplay/srp_ftc.h>
|
||||
#include <SituationReplay/srp_ftc_types.h>
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <DDS/DDSConnector/publisher.h>
|
||||
#include <DDS/DDSConnector/subscriber.h>
|
||||
|
||||
#include <Common/ProjectConfig/project_defines.h>
|
||||
#include <SituationReplay/logger.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class SrpFtTests : public QObject
|
||||
, protected SituationReplay::Interface::Ftc::ChangeReplayStateReplyHandler
|
||||
{
|
||||
using Publisher = DDSConnector::Publisher;
|
||||
using Subscriber = DDSConnector::Subscriber;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum TestId
|
||||
{
|
||||
All,
|
||||
TryStart,
|
||||
TryNotAllowedChange,
|
||||
TryChangePaused,
|
||||
TryChangeResumed,
|
||||
TryStop,
|
||||
};
|
||||
explicit SrpFtTests(QObject *parent = nullptr);
|
||||
~SrpFtTests();
|
||||
|
||||
bool init(int domainId, TestId testId, int replayPartitionId, int srpId);
|
||||
bool testsSuccessful() const { return m_bTestsSuccessful; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void startTest();
|
||||
protected Q_SLOTS:
|
||||
void tryStart();
|
||||
void tryNotAllowedChange();
|
||||
void tryChangePaused();
|
||||
void tryChangeResumed();
|
||||
void tryStop();
|
||||
protected:
|
||||
void startReplayReply(const Core::FunctionReplyObject &replyObject);
|
||||
void stopReplayReply(const Core::FunctionReplyObject &replyObject);
|
||||
void changeReplayStateReply(const Core::FunctionReplyObject &replyObject);
|
||||
void onChangeReplayStateReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void failExit();
|
||||
void switchToState(SrpState state);
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<SituationReplay::Interface::Ftc> m_ftc;
|
||||
qint32 m_replayPartitionId;
|
||||
qint32 m_situationReplayId;
|
||||
TestId m_testId;
|
||||
TestId m_currentTestId;
|
||||
bool m_bTestsSuccessful;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace SituationReplay
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* DbReader for RecordingManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#include "db_reader.h"
|
||||
|
||||
#include "logger.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
#include <LtsPluginManager/lts_plugin_loader.h>
|
||||
#include <ngldb/nsqlquery.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
DbReader::DbReader(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
||||
int exerciseId,
|
||||
bool bCanHandleSchemas)
|
||||
: m_exerciseId(exerciseId)
|
||||
, m_query(nullptr)
|
||||
, m_ddsConnector(ddsConnector)
|
||||
, m_bCanHandleSchemas(bCanHandleSchemas)
|
||||
, m_logger(getLogger("DbReader"))
|
||||
{}
|
||||
|
||||
DbReader::~DbReader()
|
||||
{
|
||||
delete m_query;
|
||||
LtsPluginManager::LtsPluginLoader::getInstance()->unloadAllPlugins();
|
||||
m_plugins.clear();
|
||||
}
|
||||
|
||||
bool DbReader::loadPlugin(const LtsPluginManager::PluginInstance &pi)
|
||||
{
|
||||
RecordReplay::RecordReplayPlugin *recPlugin = qobject_cast<RecordReplay::RecordReplayPlugin*>(pi.plugin);
|
||||
if (!recPlugin)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Cannot load RecordReplayPlugin " << pi.fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!recPlugin->initDts(m_ddsConnector, m_exerciseId, m_bCanHandleSchemas, *m_query))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation for RecordReplayPlugin " << pi.fileName << " failed ";
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "Loaded record replay plugin " << recPlugin->pluginName();
|
||||
m_plugins.push_back(recPlugin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DbReader::init(const QSqlDatabase &db)
|
||||
{
|
||||
delete m_query;
|
||||
m_query = new NSqlQuery(db);
|
||||
|
||||
auto cb = [this](const LtsPluginManager::PluginInstance &pi) { return loadPlugin(pi); };
|
||||
LtsPluginManager::LtsPluginLoader::getInstance()->loadPlugins(LtsPluginManager::PluginType::SPECIAL,
|
||||
cb,
|
||||
QStringList(),
|
||||
QStringLiteral("recordreplay"));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DbReader::setReplayStartTime(qint64 startTime)
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN setReplayStartTime " << startTime;
|
||||
if (!m_query)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Internal error - no query!";
|
||||
return false;
|
||||
}
|
||||
for (RecordReplay::RecordReplayPlugin *recPlugin : m_plugins)
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN setReplayStartTime, current Plugin: " << recPlugin->pluginName()
|
||||
<< " typename=" << typeid(*recPlugin).name();
|
||||
if (!recPlugin->setReplayStartTime(*m_query, startTime))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "setReplayStartTime for plugin " << recPlugin->svcShortName() << " failed!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
INFO_LOG(m_logger) << "IN setReplayStartTime " << startTime << " DONE";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DbReader::readData(qint64 fromTime, qint64 toTime)
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN readData " << fromTime << " to " << toTime;
|
||||
if (!m_query)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Internal error - no query!";
|
||||
return false;
|
||||
}
|
||||
for (RecordReplay::RecordReplayPlugin *recPlugin : m_plugins)
|
||||
{
|
||||
if (!recPlugin->ddsTopicsFromDatabase(*m_query, fromTime, toTime))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "ddsTopicsFromDatabase for plugin " << recPlugin->svcShortName() << " failed!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
INFO_LOG(m_logger) << "IN readData " << fromTime << " to " << toTime << " DONE";
|
||||
return true;
|
||||
}
|
||||
|
||||
void DbReader::publish(qint64 desiredTime)
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN publish " << desiredTime;
|
||||
for (RecordReplay::RecordReplayPlugin *recPlugin : m_plugins)
|
||||
if (!recPlugin->publishData(desiredTime))
|
||||
WARNING_LOG(m_logger) << "publishData for plugin " << recPlugin->svcShortName() << " failed!";
|
||||
INFO_LOG(m_logger) << "IN publish " << desiredTime << " DONE";
|
||||
}
|
||||
|
||||
void DbReader::waitForAsyncOperations(qint64 desiredTime)
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN waitForAsyncOperations " << desiredTime;
|
||||
for (RecordReplay::RecordReplayPlugin *recPlugin : m_plugins)
|
||||
if (!recPlugin->waitForAsyncOperations(desiredTime))
|
||||
WARNING_LOG(m_logger) << "waitForAsyncOperations for plugin " << recPlugin->svcShortName() << " failed!";
|
||||
}
|
||||
|
||||
|
||||
void DbReader::clearData()
|
||||
{
|
||||
INFO_LOG(m_logger) << "IN clearData";
|
||||
for (RecordReplay::RecordReplayPlugin *recPlugin : m_plugins)
|
||||
recPlugin->clearData();
|
||||
}
|
||||
|
||||
} // RecordingManagement
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* DbReader for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/record_replay_plugin.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
class QSqlDatabase;
|
||||
class NSqlQuery;
|
||||
namespace LtsPluginManager
|
||||
{
|
||||
struct PluginInstance;
|
||||
}
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
class DbReader final
|
||||
{
|
||||
public:
|
||||
explicit DbReader(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
||||
int exerciseId,
|
||||
bool bCanHandleSchemas);
|
||||
~DbReader();
|
||||
|
||||
bool init(const QSqlDatabase &db);
|
||||
|
||||
bool setReplayStartTime(qint64 startTime);
|
||||
bool readData(qint64 fromTime, qint64 toTime);
|
||||
void publish(qint64 desiredTime);
|
||||
void waitForAsyncOperations(qint64 desiredTime);
|
||||
void clearData();
|
||||
private:
|
||||
bool loadPlugin(const LtsPluginManager::PluginInstance &pi);
|
||||
private:
|
||||
int m_exerciseId;
|
||||
NSqlQuery *m_query;
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
bool m_bCanHandleSchemas;
|
||||
|
||||
std::vector<RecordReplay::RecordReplayPlugin*> m_plugins;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace RecordingManagement
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "dds_handler.h"
|
||||
|
||||
#include <DDS/DTS/generic_dts_impl.h>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
#include <QVector>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
static std::shared_ptr<DDSConnector::DdsConnector> makeConnector(const ConnectionParams ¶ms,
|
||||
IDL::PartitionType partitionType,
|
||||
DDS::QosProfile::ConnectionType defaultConnectionType)
|
||||
{
|
||||
if (params.discoveryPeer.isEmpty())
|
||||
return std::make_shared<DDSConnector::DdsConnector>(params.domainId,
|
||||
partitionType,
|
||||
params.partitionId,
|
||||
params.exerciseId,
|
||||
defaultConnectionType);
|
||||
return std::make_shared<DDSConnector::DdsConnector>(params.domainId,
|
||||
partitionType,
|
||||
params.partitionId,
|
||||
params.exerciseId,
|
||||
params.discoveryPeer);
|
||||
}
|
||||
|
||||
DdsHandler::DdsHandler(const ConnectionParams &output)
|
||||
: m_ddsConnectorReplay(makeConnector(output, IDL::PartitionType::Replay, DDS::QosProfile::ConnectionType::ShmUdpLocalhost))
|
||||
, m_logger(getLogger("DdsHandler"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DdsHandler Replay(" << output.partitionId << ") for partition: " << m_ddsConnectorReplay->getDefaultPartition();
|
||||
}
|
||||
|
||||
DdsHandler::DdsHandler(const ConnectionParams &input, const ConnectionParams &output)
|
||||
: m_ddsConnectorExercise(makeConnector(input, IDL::PartitionType::Exercise, DDS::QosProfile::ConnectionType::Client))
|
||||
, m_ddsConnectorReplay(makeConnector(output, IDL::PartitionType::Replay, DDS::QosProfile::ConnectionType::Shm))
|
||||
, m_logger(getLogger("DdsHandler"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DdsHandler Exercise(" << input.partitionId << ") for partition: " << m_ddsConnectorExercise->getDefaultPartition();
|
||||
DEBUG_LOG(m_logger) << "DdsHandler Replay(" << output.partitionId << ") for partition: " << m_ddsConnectorReplay->getDefaultPartition();
|
||||
}
|
||||
|
||||
DdsHandler::~DdsHandler()
|
||||
{
|
||||
m_sessionRouting = nullptr;
|
||||
m_dtsPartitionTime = nullptr;
|
||||
m_ddsFts = nullptr;
|
||||
m_ddsDts = nullptr;
|
||||
m_ddsConnectorReplay = nullptr;
|
||||
m_ddsConnectorExercise = nullptr;
|
||||
}
|
||||
|
||||
bool DdsHandler::init(const QStringList &qosFileList)
|
||||
{
|
||||
if ((m_ddsConnectorExercise && !m_ddsConnectorExercise->init(qosFileList)) ||
|
||||
!m_ddsConnectorReplay->init(qosFileList))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_ddsConnectorExercise)
|
||||
{
|
||||
m_ddsConnectorExercise->initPublisherSubscriber();
|
||||
m_ddsConnectorExercise->enableBatchedWriter(false);
|
||||
}
|
||||
|
||||
m_ddsConnectorReplay->initPublisherSubscriber();
|
||||
m_ddsConnectorReplay->enableBatchedWriter(false);
|
||||
|
||||
m_dtsPartitionTime.reset(m_ddsConnectorReplay->createDTS<DTS::PartitionTimeImpl>());
|
||||
assert(m_dtsPartitionTime.get());
|
||||
|
||||
m_ddsDts = SituationReplay::Interface::Dts::create(m_ddsConnectorReplay);
|
||||
m_ddsFts = SituationReplay::Interface::Fts::create(m_ddsConnectorReplay);
|
||||
bool bRet = m_ddsDts->enableAll();
|
||||
INFO_LOG(m_logger) << "Dts initialised";
|
||||
|
||||
bRet &= m_ddsFts->enableAll();
|
||||
INFO_LOG(m_logger) << "Fts initialised";
|
||||
|
||||
initReplayRouting();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void DdsHandler::publishPartitionTime(const Core::PartitionTime &partitionTime)
|
||||
{
|
||||
INFO_LOG(m_logger) << "publish partitionTime: " << partitionTime.timeStamp();
|
||||
m_dtsPartitionTime->write(partitionTime);
|
||||
}
|
||||
|
||||
bool DdsHandler::parseOptions(const QString &opts, ConnectionParams ¶ms)
|
||||
{
|
||||
QVector<QStringRef> parts = opts.splitRef(QLatin1Char(','));
|
||||
if (parts.size() < 2 || parts.size() > 3)
|
||||
return false;
|
||||
bool bOk;
|
||||
params.domainId = parts.at(0).toInt(&bOk);
|
||||
if (!bOk)
|
||||
return false;
|
||||
params.partitionId = parts.at(1).toInt(&bOk);
|
||||
if (!bOk)
|
||||
return false;
|
||||
if (parts.size() == 3)
|
||||
{
|
||||
QString str = parts.at(2).toString();
|
||||
// '_' is not allowed in a scheme, but rti needs it ...
|
||||
str.replace(QLatin1String("tcpv4_lan"), QLatin1String("tcpv4lan"));
|
||||
QUrl url = QUrl::fromUserInput(str);
|
||||
if (url.scheme() == QLatin1String("http") ||
|
||||
url.scheme() == QLatin1String("file"))
|
||||
url.setScheme(QStringLiteral("tcpv4lan"));
|
||||
if (!url.isValid())
|
||||
return false;
|
||||
params.discoveryPeer = url;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DdsHandler::initReplayRouting()
|
||||
{
|
||||
if (!m_ddsConnectorExercise)
|
||||
return;
|
||||
m_sessionRouting.reset(new RoutingService::SessionHandler(IDL::PartitionType::Replay,
|
||||
m_ddsConnectorExercise,
|
||||
m_ddsConnectorReplay));
|
||||
m_sessionRouting->init();
|
||||
m_sessionRouting->onCreateSession(QString::fromStdString(m_ddsConnectorExercise->getDefaultPartition()),
|
||||
QString::fromStdString(m_ddsConnectorReplay->getDefaultPartition()));
|
||||
}
|
||||
|
||||
} // Namespace SRP
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <RoutingServiceNG/session_handler.h>
|
||||
|
||||
#include <SituationReplay/srp_dts.h>
|
||||
#include <SituationReplay/srp_fts.h>
|
||||
#include <DDS/Core/core_dts_types.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
struct ConnectionParams
|
||||
{
|
||||
int domainId = 0;
|
||||
int partitionId = 0;
|
||||
int exerciseId = 0;
|
||||
|
||||
QUrl discoveryPeer;
|
||||
};
|
||||
|
||||
class DdsHandler final
|
||||
{
|
||||
public:
|
||||
explicit DdsHandler(const SituationReplay::ConnectionParams &output);
|
||||
DdsHandler(const SituationReplay::ConnectionParams &input,
|
||||
const SituationReplay::ConnectionParams &output);
|
||||
~DdsHandler();
|
||||
|
||||
bool init(const QStringList &qosFileList = QStringList());
|
||||
|
||||
void publishPartitionTime(const Core::PartitionTime &partitionTime);
|
||||
|
||||
std::shared_ptr<SituationReplay::Interface::Dts> dts() const { return m_ddsDts; }
|
||||
std::shared_ptr<SituationReplay::Interface::Fts> fts() const { return m_ddsFts; }
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsExercise() const { return m_ddsConnectorExercise; }
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsReplay() const { return m_ddsConnectorReplay; }
|
||||
|
||||
static bool parseOptions(const QString &opts, ConnectionParams ¶ms);
|
||||
|
||||
private:
|
||||
void initReplayRouting();
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorExercise;
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorReplay;
|
||||
std::shared_ptr<SituationReplay::Interface::Dts> m_ddsDts;
|
||||
std::shared_ptr<SituationReplay::Interface::Fts> m_ddsFts;
|
||||
std::unique_ptr<DTS::PartitionTime> m_dtsPartitionTime;
|
||||
std::unique_ptr<RoutingService::SessionHandler> m_sessionRouting;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for all request journal objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-01-13
|
||||
*/
|
||||
|
||||
#include "handler_situation_replay.h"
|
||||
#include "object_situation_replay.h"
|
||||
#include "db_reader.h"
|
||||
#include <SituationReplay/srp_db.h>
|
||||
|
||||
#include <ngldb/nsqlquery.h>
|
||||
#include <QCoreApplication>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
HandlerSituationReplay::HandlerSituationReplay(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<DbReader> &dbReader)
|
||||
: Interface::Fts::ChangeReplayStateRequestHandler(ddsHandler->fts())
|
||||
, m_objSrp(nullptr)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_db(db)
|
||||
, m_dbReader(dbReader)
|
||||
, m_exerciseId(0)
|
||||
, m_partitionId(0)
|
||||
, m_logger(getLogger("HandlerSituationReplay"))
|
||||
{}
|
||||
|
||||
HandlerSituationReplay::~HandlerSituationReplay()
|
||||
{
|
||||
delete m_objSrp;
|
||||
}
|
||||
|
||||
bool HandlerSituationReplay::init(int exerciseId, int partitionId)
|
||||
{
|
||||
m_exerciseId = exerciseId;
|
||||
m_partitionId = partitionId;
|
||||
|
||||
const QString tableName = m_db->schemaName().isEmpty() ? QStringLiteral("exercise") : QStringLiteral("exm.exercise");
|
||||
const QString stmt(QStringLiteral("SELECT start_time FROM %1 WHERE id = %2").arg(tableName).arg(exerciseId));
|
||||
NSqlQuery q(m_db->database());
|
||||
const qint64 exerciseStartTime = (q.execAndFetch(stmt) ? q.value(0).toLongLong() : 0);
|
||||
|
||||
DEBUG_LOG(m_logger) << "stmt: " << stmt << ", res " << exerciseStartTime;
|
||||
|
||||
Database::SrpSituationReplay newData;
|
||||
newData.srpStateId = SrpState::Stopped;
|
||||
newData.replayPartitionId = m_partitionId;
|
||||
newData.beginTime = exerciseStartTime;
|
||||
newData.endTime = exerciseStartTime;
|
||||
newData.pace = 0.0;
|
||||
|
||||
return createObject(newData);
|
||||
}
|
||||
|
||||
bool HandlerSituationReplay::createObject(const Database::SrpSituationReplay &newData)
|
||||
{
|
||||
delete m_objSrp;
|
||||
m_objSrp = new ObjectSituationReplay(m_ddsHandler, m_db, m_dbReader, m_exerciseId);
|
||||
Core::FunctionReplyObject ret = m_objSrp->createObject(newData);
|
||||
if (ret.error())
|
||||
{
|
||||
delete m_objSrp;
|
||||
m_objSrp = nullptr;
|
||||
ERROR_LOG(m_logger) << ret();
|
||||
}
|
||||
return m_objSrp != nullptr;
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject HandlerSituationReplay::startReplayRequest(const SituationReplay::ChangeReplayStateRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onStartReplayRequest: " << request;
|
||||
// Start only own replay
|
||||
if (request.replayPartitionId() != m_partitionId)
|
||||
return Core::FunctionReplyObject(request.replayPartitionId(),tr_lts("dds", "Wrong replay partition"));
|
||||
if (m_objSrp && m_objSrp->srpState() != SrpState::Stopped)
|
||||
return Core::FunctionReplyObject(request.replayPartitionId(), tr_lts("dds", "Replay is not yet stopped"));
|
||||
|
||||
Database::SrpSituationReplay newData;
|
||||
newData.srpStateId = SrpState::Started;
|
||||
newData.replayPartitionId = m_partitionId;
|
||||
newData.beginTime = request.beginTime();
|
||||
newData.endTime = request.endTime();
|
||||
newData.pace = request.pace().is_set() ? request.pace().get() : 1;
|
||||
|
||||
// round to sec
|
||||
newData.beginTime = (newData.beginTime / 1000) * 1000;
|
||||
if (newData.endTime)
|
||||
newData.endTime = ((newData.endTime / 1000) + 1) * 1000;
|
||||
|
||||
if (!m_objSrp && !createObject(newData))
|
||||
return Core::FunctionReplyObject(request.replayPartitionId(),tr_lts("dds", "Internal error"));
|
||||
|
||||
m_objSrp->setSrpData(newData);
|
||||
return Core::FunctionReplyObject(m_objSrp->getId());
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject HandlerSituationReplay::stopReplayRequest(const SituationReplay::ChangeReplayStateRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onStopReplayRequest: " << request;
|
||||
|
||||
if (m_objSrp == nullptr)
|
||||
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "SituationReplay for replayPartitionId %1 not found")).arg(request.replayPartitionId());
|
||||
|
||||
if (m_objSrp && (m_objSrp->getId() != request.id() || m_objSrp->getReplayPartitionId() != request.replayPartitionId()))
|
||||
return Core::FunctionReplyObject(request.id(),tr_lts("dds", "Given request id %1 not equal object id %2")).arg(request.id()).arg(m_objSrp->getId());
|
||||
|
||||
Core::FunctionReplyObject ret = m_objSrp->switchToState(SrpState::Stopped);
|
||||
if (!ret.error())
|
||||
ret = m_objSrp->removeObject();
|
||||
|
||||
// remove all old data from DDS-Bus & clear maps
|
||||
m_dbReader->clearData();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject HandlerSituationReplay::changeReplayStateRequest(const SituationReplay::ChangeReplayStateRequest &request)
|
||||
{
|
||||
if (request.state() != SrpState_def::Started)
|
||||
{
|
||||
if (m_objSrp == nullptr)
|
||||
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "SituationReplay for replayPartitionId %1 not found")).arg(request.replayPartitionId());
|
||||
|
||||
if (m_objSrp && (m_objSrp->getId() != request.id() || m_objSrp->getReplayPartitionId() != request.replayPartitionId()))
|
||||
return Core::FunctionReplyObject(request.id(),tr_lts("dds", "Given request id %1 not equal object id %2")).arg(request.id()).arg(m_objSrp->getId());
|
||||
}
|
||||
|
||||
if (request.pace().is_set())
|
||||
m_objSrp->setPace(request.pace().get());
|
||||
|
||||
switch (request.state().underlying())
|
||||
{
|
||||
case SrpState_def::Unknown:
|
||||
if (request.pace().is_set())
|
||||
return Core::FunctionReplyObject(request.id());
|
||||
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not handle command 'Unknown' in changeReplayStateRequest"));
|
||||
case SrpState_def::Started:
|
||||
return startReplayRequest(request);
|
||||
case SrpState_def::Resumed:
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Resume request: " << request.beginTime() << ", cur playback time: " << m_objSrp->currentReplayTime();
|
||||
if (request.beginTime() != 0 && request.beginTime() != m_objSrp->currentReplayTime())
|
||||
{
|
||||
stopReplayRequest(request);
|
||||
return startReplayRequest(request);
|
||||
}
|
||||
Q_FALLTHROUGH();
|
||||
case SrpState_def::Paused:
|
||||
return m_objSrp->switchToState(request.state());
|
||||
}
|
||||
case SrpState_def::Stopped:
|
||||
return stopReplayRequest(request);
|
||||
}
|
||||
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Unhandled request state %1")).arg(request.state().underlying());
|
||||
}
|
||||
|
||||
void HandlerSituationReplay::onChangeReplayStateRequest(const rti::core::SampleIdentity &cookie,
|
||||
const ChangeReplayStateRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onChangeReplayStateRequest: " << request;
|
||||
auto ret = changeReplayStateRequest(request);
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
m_ddsHandler->fts()->changeReplayStateReply(cookie, ret);
|
||||
}
|
||||
|
||||
} // Namespace SituationReplay
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for all situation replay objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
#include <SituationReplay/srp_fts.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
namespace Database
|
||||
{
|
||||
struct SrpSituationReplay;
|
||||
}
|
||||
class DatabaseInterface;
|
||||
class DbReader;
|
||||
class DdsHandler;
|
||||
class ObjectSituationReplay;
|
||||
class HandlerSituationReplay final : public QObject
|
||||
, protected Interface::Fts::ChangeReplayStateRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerSituationReplay(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<DbReader> &dbReader);
|
||||
~HandlerSituationReplay();
|
||||
|
||||
bool init(int exerciseId, int partitionId);
|
||||
|
||||
private:
|
||||
bool createObject(const Database::SrpSituationReplay &newData);
|
||||
Core::FunctionReplyObject startReplayRequest(const ChangeReplayStateRequest &request);
|
||||
Core::FunctionReplyObject stopReplayRequest(const ChangeReplayStateRequest &request);
|
||||
Core::FunctionReplyObject changeReplayStateRequest(const ChangeReplayStateRequest &request);
|
||||
|
||||
void onChangeReplayStateRequest(const rti::core::SampleIdentity &cookie,
|
||||
const ChangeReplayStateRequest &request) override;
|
||||
|
||||
private:
|
||||
ObjectSituationReplay *m_objSrp; // only one (!) replay per partition possible
|
||||
const std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
const std::shared_ptr<DatabaseInterface> m_db;
|
||||
const std::shared_ptr<DbReader> m_dbReader;
|
||||
|
||||
int m_exerciseId;
|
||||
int m_partitionId;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for all request journal objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-01-13
|
||||
*/
|
||||
|
||||
#include "handler_situation_replay_sqlite.h"
|
||||
#include "object_situation_replay.h"
|
||||
#include "db_reader.h"
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
HandlerSituationReplaySqlite::HandlerSituationReplaySqlite(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DbReader> &dbReader)
|
||||
: m_objSrp(nullptr)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_dbReader(dbReader)
|
||||
, m_exerciseId(0)
|
||||
, m_partitionId(0)
|
||||
, m_beginTime(0)
|
||||
, m_endTime(0)
|
||||
, m_logger(getLogger("HandlerSituationReplaySqlite"))
|
||||
{}
|
||||
|
||||
HandlerSituationReplaySqlite::~HandlerSituationReplaySqlite()
|
||||
{
|
||||
delete m_objSrp;
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::init(int exerciseId, int partitionId, qint64 beginTime, qint64 endTime)
|
||||
{
|
||||
m_exerciseId = exerciseId;
|
||||
m_partitionId = partitionId;
|
||||
m_beginTime = beginTime;
|
||||
m_endTime = endTime;
|
||||
|
||||
Database::SrpSituationReplay newData;
|
||||
newData.srpStateId = SrpState::Stopped;
|
||||
newData.replayPartitionId = m_partitionId;
|
||||
newData.beginTime = m_beginTime;
|
||||
newData.endTime = m_beginTime; // for init
|
||||
newData.pace = 0.0;
|
||||
|
||||
createObject(newData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::createObject(const Database::SrpSituationReplay &newData)
|
||||
{
|
||||
delete m_objSrp;
|
||||
m_objSrp = new ObjectSituationReplay(m_ddsHandler, nullptr, m_dbReader, m_exerciseId);
|
||||
Core::FunctionReplyObject ret = m_objSrp->createObject(newData);
|
||||
if (ret.error())
|
||||
{
|
||||
delete m_objSrp;
|
||||
m_objSrp = nullptr;
|
||||
ERROR_LOG(m_logger) << ret();
|
||||
return false;
|
||||
}
|
||||
connect(m_objSrp, &ObjectSituationReplay::replayTimeChanged, this, &HandlerSituationReplaySqlite::replayTimeChanged);
|
||||
connect(m_objSrp, &ObjectSituationReplay::started, this, &HandlerSituationReplaySqlite::started);
|
||||
connect(m_objSrp, &ObjectSituationReplay::paused, this, &HandlerSituationReplaySqlite::paused);
|
||||
connect(m_objSrp, &ObjectSituationReplay::resumed, this, &HandlerSituationReplaySqlite::resumed);
|
||||
connect(m_objSrp, &ObjectSituationReplay::stopped, this, &HandlerSituationReplaySqlite::stopped);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::onStartReplayRequest(qint64 begin, qint64 end, double pace)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onStartReplayRequest: " << begin << ", " << end << ", " << pace;
|
||||
|
||||
Database::SrpSituationReplay newData;
|
||||
newData.srpStateId = SrpState::Started;
|
||||
newData.replayPartitionId = m_partitionId;
|
||||
newData.beginTime = begin;
|
||||
newData.endTime = end;
|
||||
newData.pace = pace;
|
||||
|
||||
if (!m_objSrp && !createObject(newData))
|
||||
return false;
|
||||
return m_objSrp->setSrpData(newData);
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::onStopReplayRequest()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onStopReplayRequest";
|
||||
|
||||
if (m_objSrp == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onStopReplayRequest - internal error";
|
||||
return false;
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ret = m_objSrp->switchToState(SrpState::Stopped);
|
||||
if (!ret.error())
|
||||
ret = m_objSrp->removeObject();
|
||||
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
|
||||
// remove all old data from DDS-Bus & clear maps
|
||||
m_dbReader->clearData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::onPauseReplayRequest()
|
||||
{
|
||||
if (m_objSrp == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onChangeReplayStateRequest - internal error";
|
||||
return false;
|
||||
}
|
||||
return onChangeReplayStateRequest(SrpState::Paused, m_objSrp->pace());
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::onResumeReplayRequest()
|
||||
{
|
||||
if (m_objSrp == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onChangeReplayStateRequest - internal error";
|
||||
return false;
|
||||
}
|
||||
return onChangeReplayStateRequest(SrpState::Resumed, m_objSrp->pace());
|
||||
}
|
||||
|
||||
|
||||
bool HandlerSituationReplaySqlite::onChangeReplayStateRequest(const SituationReplay::SrpState &newState, double newPace)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onChangeReplayStateRequest: " << newState << ", " << newPace;
|
||||
|
||||
if (m_objSrp == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onChangeReplayStateRequest - internal error";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newState != SrpState::Resumed && newState != SrpState::Paused)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onChangeReplayStateRequest: SrpStateChange not possible, only resumed & paused allowed";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_objSrp->setPace(newPace);
|
||||
const Core::FunctionReplyObject ret = m_objSrp->switchToState(newState);
|
||||
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
|
||||
return !ret.error();
|
||||
}
|
||||
|
||||
bool HandlerSituationReplaySqlite::onPaceChangeRequest(double newPace)
|
||||
{
|
||||
if (m_objSrp == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onChangeReplayStateRequest - internal error";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_objSrp->setPace(newPace);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // Namespace SituationReplay
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for all situation replay objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SituationReplay/situationreplaysqlite_export.h>
|
||||
#include <SituationReplay/srp_enums.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
namespace Database
|
||||
{
|
||||
struct SrpSituationReplay;
|
||||
}
|
||||
class DbReader;
|
||||
class DdsHandler;
|
||||
class ObjectSituationReplay;
|
||||
class SITUATIONREPLAYSQLITE_EXPORT HandlerSituationReplaySqlite final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerSituationReplaySqlite(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DbReader> &dbReader);
|
||||
~HandlerSituationReplaySqlite();
|
||||
|
||||
bool init(int exerciseId, int partitionId, qint64 beginTime, qint64 endTime);
|
||||
qint64 beginTime() const { return m_beginTime; }
|
||||
qint64 endTime() const { return m_endTime; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void replayTimeChanged(qint64 curTime);
|
||||
void started(qint64 currentReplayTime);
|
||||
void paused();
|
||||
void resumed(qint64 currentReplayTime);
|
||||
void stopped();
|
||||
public:
|
||||
bool onStartReplayRequest(double pace) { return onStartReplayRequest(m_beginTime, m_endTime, pace); }
|
||||
bool onStartReplayRequest(qint64 begin, qint64 end, double pace);
|
||||
bool onStopReplayRequest();
|
||||
bool onPauseReplayRequest();
|
||||
bool onResumeReplayRequest();
|
||||
bool onChangeReplayStateRequest(const SrpState &newState, double newPace);
|
||||
bool onPaceChangeRequest(double newPace);
|
||||
private:
|
||||
bool createObject(const Database::SrpSituationReplay &newData);
|
||||
private:
|
||||
ObjectSituationReplay *m_objSrp; // only one (!) replay per partition possible
|
||||
const std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
const std::shared_ptr<DbReader> m_dbReader;
|
||||
|
||||
int m_exerciseId;
|
||||
int m_partitionId;
|
||||
qint64 m_beginTime;
|
||||
qint64 m_endTime;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: SituationReplay
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.SRP=WARN
|
||||
#log4j.logger.SRP.main=WARN
|
||||
#log4j.logger.SRP.HandlerSituationReplay=INFO
|
||||
#log4j.logger.SRP.ObjectSituationReplay=INFO
|
||||
#log4j.logger.SRP.Settings=INFO
|
||||
#log4j.logger.SRP.DbHandler=DEBUG
|
||||
#log4j.logger.SRP.DdsHandler=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
+36
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "SRP.";
|
||||
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 SituationReplay
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "srp_export.h"
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
SRP_COMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace SituationReplay
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* main for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "main_handler.h"
|
||||
#include "logger.h"
|
||||
#include "settings.h"
|
||||
|
||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
||||
{
|
||||
public:
|
||||
CmdLineParser()
|
||||
: LtsCommandLineParser(ProvideCommandLineParameterOptions(CreateDomainIdFromIp|DomainId|ExerciseId))
|
||||
{
|
||||
addOption({ QStringList() << QLatin1String("input"),
|
||||
QLatin1String("information for the input side (domainId,exerciseId,<tcpConnectionParams>"),
|
||||
QLatin1String("1,42,tcpv4lan://srv:port"),
|
||||
QString()
|
||||
});
|
||||
addOption({ QStringList() << QLatin1String("output"),
|
||||
QLatin1String("information for the output side (domainId,replayId,<tcpConnectionParams>"),
|
||||
QLatin1String("2,1,tcpv4lan://srv:port"),
|
||||
QString()
|
||||
});
|
||||
}
|
||||
|
||||
QString inputParams() const { return isSet(QLatin1String("input")) ? value(QLatin1String("input")) : QString(); }
|
||||
QString outputParams() const { return isSet(QLatin1String("output")) ? value(QLatin1String("output")) : QString(); }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
|
||||
CmdLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
SituationReplay::ConnectionParams input, output;
|
||||
if (!SituationReplay::DdsHandler::parseOptions(options.inputParams(), input))
|
||||
{
|
||||
app.createLogger("SRP", options.exerciseId());
|
||||
ERROR_LOG(app.baseLogger()) << "Can not parse input params: '" << options.inputParams() << "'";
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!SituationReplay::DdsHandler::parseOptions(options.outputParams(), output))
|
||||
{
|
||||
app.createLogger("SRP", options.exerciseId());
|
||||
ERROR_LOG(app.baseLogger()) << "Can not parse output params: '" << options.outputParams() << "'";
|
||||
return -3;
|
||||
}
|
||||
//set output exercise id = input exercise id
|
||||
input.exerciseId = input.partitionId;
|
||||
output.exerciseId = input.partitionId;
|
||||
app.createLogger("SRP", input.partitionId, output.partitionId);
|
||||
|
||||
SituationReplay::Settings::setIniFile(options.iniFile());
|
||||
|
||||
int iRet = -4;
|
||||
{
|
||||
std::unique_ptr<SituationReplay::MainHandler> mainHandler(new SituationReplay::MainHandler);
|
||||
|
||||
NOTICE_LOG(app.baseLogger()) << "Input domainId: " << input.domainId
|
||||
<< ", partition id: " << input.partitionId
|
||||
<< ", exercise id: " << input.exerciseId
|
||||
<< (input.discoveryPeer.isEmpty() ? QString() : QStringLiteral(", discovery: ") + input.discoveryPeer.toString());
|
||||
NOTICE_LOG(app.baseLogger()) << "Output domainId: " << output.domainId
|
||||
<< ", replayId: " << output.partitionId
|
||||
<< ", exerciseid: " << output.exerciseId
|
||||
<< (output.discoveryPeer.isEmpty() ? QString() : QStringLiteral(", discovery: ") + output.discoveryPeer.toString());
|
||||
|
||||
|
||||
if (!mainHandler->init(input, output))
|
||||
return iRet;
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
iRet = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* MainHandler for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "settings.h"
|
||||
#include "db_reader.h"
|
||||
|
||||
#include "handler_situation_replay.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <ngldb/db_service_handler.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
|
||||
MainHandler::MainHandler()
|
||||
: m_handlerSrp(nullptr)
|
||||
, m_ddsInterface(nullptr)
|
||||
, m_dbHandler(nullptr)
|
||||
, m_logger(getLogger("MainHandler"))
|
||||
{}
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
m_dbReader = nullptr;
|
||||
m_handlerSrp = nullptr;
|
||||
m_ddsInterface = nullptr;
|
||||
m_dbHandler = nullptr;
|
||||
}
|
||||
|
||||
bool MainHandler::init(const SituationReplay::ConnectionParams &input,
|
||||
const SituationReplay::ConnectionParams &output)
|
||||
{
|
||||
// initialize database
|
||||
m_dbHandler = std::make_shared<DbHandler>();
|
||||
if (!m_dbHandler->init(input.partitionId, Settings::settings()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation dbHandler failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize DDS
|
||||
m_ddsInterface = std::make_shared<DdsHandler>(input, output);
|
||||
if (!m_ddsInterface->init())
|
||||
return false;
|
||||
|
||||
m_dbReader = std::make_shared<DbReader>(m_ddsInterface->ddsReplay(), input.partitionId, true);
|
||||
if (!m_dbReader->init(m_dbHandler->db()->database()))
|
||||
return false;
|
||||
|
||||
// read project specific data from database
|
||||
// publish project specific data
|
||||
// initialize the specific handler
|
||||
if (!initSrpHandler(input.partitionId, output.partitionId))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainHandler::initSrpHandler(int partitionIdIn, int partitionIdOut)
|
||||
{
|
||||
m_handlerSrp.reset(new HandlerSituationReplay(m_ddsInterface, m_dbHandler->db(), m_dbReader));
|
||||
|
||||
if (!m_handlerSrp->init(partitionIdIn, partitionIdOut))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace SituationReplay
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* MainHandler for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
#include <SituationReplay/srp_db.h>
|
||||
|
||||
namespace NGLDB
|
||||
{
|
||||
template <typename DB> class DbServiceHandler;
|
||||
}
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class DbReader;
|
||||
class HandlerSituationReplay;
|
||||
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
|
||||
|
||||
class MainHandler final
|
||||
{
|
||||
public:
|
||||
MainHandler();
|
||||
~MainHandler();
|
||||
|
||||
bool init(const ConnectionParams &input,
|
||||
const ConnectionParams &output);
|
||||
|
||||
private:
|
||||
bool initSrpHandler(int partitionIdIn, int partitionIdOut);
|
||||
|
||||
private:
|
||||
std::unique_ptr<HandlerSituationReplay> m_handlerSrp;
|
||||
std::shared_ptr<DdsHandler> m_ddsInterface;
|
||||
std::shared_ptr<DbHandler> m_dbHandler;
|
||||
std::shared_ptr<DbReader> m_dbReader;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
} // namespace SituationReplay
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* MainHandlerSqlite for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "main_handler_sqlite.h"
|
||||
|
||||
#include "db_reader.h"
|
||||
#include "static_publisher.h"
|
||||
#include "handler_situation_replay_sqlite.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <ngldb/db_service_handler.h>
|
||||
#include <ngldb/nsqlquery.h>
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QSet>
|
||||
#include <QSqlError>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
MainHandlerSqlite::MainHandlerSqlite()
|
||||
: m_curFilterArrayIdx(-1)
|
||||
, m_curOverlayArrayIdx(-1)
|
||||
, m_handlerSrp(nullptr)
|
||||
, m_staticPublisher(nullptr)
|
||||
, m_ddsInterface(nullptr)
|
||||
, m_dbHandler(nullptr)
|
||||
, m_logger(getLogger("MainHandlerSqlite"))
|
||||
{}
|
||||
|
||||
MainHandlerSqlite::~MainHandlerSqlite()
|
||||
{
|
||||
m_dbSqlite.close();
|
||||
m_dbSqlite = QSqlDatabase();
|
||||
|
||||
m_staticPublisher = nullptr;
|
||||
m_dbReader = nullptr;
|
||||
m_handlerSrp = nullptr;
|
||||
|
||||
m_ddsInterface = nullptr;
|
||||
m_dbHandler = nullptr;
|
||||
}
|
||||
|
||||
bool MainHandlerSqlite::initDb(const ReplayInformation &replayInformation,
|
||||
const QVector<FilterInformation> &filter,
|
||||
const QVector<FilterInformation> &overlays)
|
||||
{
|
||||
if (!m_ddsInterface)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "dds must be initialized first!";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_replay = replayInformation;
|
||||
// sort filter & overlays by begin time
|
||||
const auto cbSort = [](const FilterInformation &a, const FilterInformation &b)
|
||||
{
|
||||
if (a.relativeTimeSpan.begin != b.relativeTimeSpan.begin)
|
||||
return a.relativeTimeSpan.begin < b.relativeTimeSpan.begin;
|
||||
return a.overlayId < b.overlayId;
|
||||
};
|
||||
m_filter = filter;
|
||||
std::sort(m_filter.begin(), m_filter.end(), cbSort);
|
||||
m_curFilterArrayIdx = -1;
|
||||
|
||||
m_overlays = overlays;
|
||||
std::sort(m_overlays.begin(), m_overlays.end(), cbSort);
|
||||
m_curOverlayArrayIdx = -1;
|
||||
|
||||
m_staticPublisher = nullptr;
|
||||
m_handlerSrp = nullptr;
|
||||
m_dbReader = nullptr;
|
||||
m_dbHandler = nullptr;
|
||||
if (m_dbSqlite.isOpen())
|
||||
{
|
||||
m_dbSqlite.close();
|
||||
m_dbSqlite = QSqlDatabase();
|
||||
QSqlDatabase::removeDatabase(QStringLiteral("sqliteDb"));
|
||||
}
|
||||
// initialize database
|
||||
m_dbSqlite = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), QStringLiteral("sqliteDb"));
|
||||
m_dbSqlite.setDatabaseName(replayInformation.databaseFilePath);
|
||||
if (!m_dbSqlite.open())
|
||||
{
|
||||
const QString err = m_dbSqlite.lastError().nativeErrorCode();
|
||||
FATAL_LOG(m_logger) << "Error opening database '" << replayInformation.databaseFilePath << "'";
|
||||
FATAL_LOG(m_logger) << m_dbSqlite.lastError().driverText() << " "
|
||||
<< m_dbSqlite.lastError().databaseText() << " " << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString stmt(QStringLiteral("SELECT id FROM exercise"));
|
||||
NSqlQuery q(stmt, m_dbSqlite);
|
||||
const int partitionIdIn = (q.execAndFetch() ? q.value(0).toInt() : 0);
|
||||
|
||||
m_dbHandler = std::make_shared<DbHandler>();
|
||||
if (!m_dbHandler->init(partitionIdIn, m_dbSqlite))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation dbHandler failed.";
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "opening sqlite db successful";
|
||||
|
||||
m_dbReader = std::make_shared<DbReader>(m_ddsInterface->ddsReplay(), partitionIdIn, false);
|
||||
if (!m_dbReader->init(m_dbHandler->db()->database()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not initialize database reader";
|
||||
return false;
|
||||
}
|
||||
|
||||
// read project specific data from database
|
||||
// publish project specific data
|
||||
// initialize the specific handler
|
||||
if (!initSrpHandler(partitionIdIn, m_ddsInterface->ddsReplay()->getPartitionId(),
|
||||
replayInformation.timeSpan.begin, replayInformation.timeSpan.end))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not initialize situation replay handler";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!initStaticPublisher())
|
||||
return false;
|
||||
|
||||
if (!loadReplayConfig(replayInformation.replayConfigPath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainHandlerSqlite::initDds(const SituationReplay::ConnectionParams &output)
|
||||
{
|
||||
// initialize DDS
|
||||
m_ddsInterface = std::make_shared<DdsHandler>(output);
|
||||
if (!m_ddsInterface->init())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> MainHandlerSqlite::ddsReplay() const
|
||||
{
|
||||
return m_ddsInterface->ddsReplay();
|
||||
}
|
||||
|
||||
bool MainHandlerSqlite::initSrpHandler(int partitionIdIn, int partitionIdOut, qint64 beginTime, qint64 endTime)
|
||||
{
|
||||
m_handlerSrp.reset(new HandlerSituationReplaySqlite(m_ddsInterface, m_dbReader));
|
||||
|
||||
if (!m_handlerSrp->init(partitionIdIn, partitionIdOut, beginTime, endTime))
|
||||
return false;
|
||||
|
||||
connect(m_handlerSrp.get(), &HandlerSituationReplaySqlite::replayTimeChanged,
|
||||
this, &MainHandlerSqlite::onReplayTimeChanged);
|
||||
connect(m_handlerSrp.get(), &HandlerSituationReplaySqlite::started,
|
||||
this, &MainHandlerSqlite::onReplayTimeMaybeJumped);
|
||||
connect(m_handlerSrp.get(), &HandlerSituationReplaySqlite::resumed,
|
||||
this, &MainHandlerSqlite::onReplayTimeMaybeJumped);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainHandlerSqlite::initStaticPublisher()
|
||||
{
|
||||
m_staticPublisher.reset(new StaticPublisher(m_ddsInterface, m_dbSqlite));
|
||||
connect(m_staticPublisher.get(), &StaticPublisher::fileContentAvailable,
|
||||
this, &MainHandlerSqlite::fileContentAvailable);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MainHandlerSqlite::loadReplayConfig(const QString &replayConfigPath)
|
||||
{
|
||||
QFile f(replayConfigPath);
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not open '" << replayConfigPath << "' for reading - no replay config loaded";
|
||||
return false;
|
||||
}
|
||||
QJsonParseError error;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(f.readAll(), &error));
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse replay config loaded json file: " << error.errorString();
|
||||
return false;
|
||||
}
|
||||
const QJsonObject obj = doc.object();
|
||||
const double replaySpeed = obj[QStringLiteral("speed")].toDouble(1.0);
|
||||
emit initialReplaySpeed(replaySpeed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::onReplayTimeChanged(qint64 curTime)
|
||||
{
|
||||
maybeApplyNextFilter(curTime);
|
||||
maybeAddNewOverlay(curTime);
|
||||
removeOutdatedOverlays(curTime);
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::onReplayTimeMaybeJumped(qint64 curTime)
|
||||
{
|
||||
replayTimeMaybeJumpedFilter(curTime);
|
||||
replayTimeMaybeJumpedOverlays(curTime);
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::maybeApplyNextFilter(qint64 curTime)
|
||||
{
|
||||
const int nextIdx = findNextIndex(curTime,
|
||||
m_curFilterArrayIdx,
|
||||
m_filter);
|
||||
if (nextIdx < 0)
|
||||
return;
|
||||
m_curFilterArrayIdx = nextIdx;
|
||||
emit applyCurentFilter(m_filter.at(m_curFilterArrayIdx));
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::replayTimeMaybeJumpedFilter(qint64 curTime)
|
||||
{
|
||||
const qint64 curTimeRelative = curTime - m_replay.timeSpan.begin;
|
||||
m_curFilterArrayIdx = -1;
|
||||
for (int i = 0; i < m_filter.size(); ++i)
|
||||
{
|
||||
const auto &filter = m_filter.at(i);
|
||||
if (filter.relativeTimeSpan.begin > curTimeRelative)
|
||||
break;
|
||||
m_curFilterArrayIdx = i;
|
||||
}
|
||||
if (m_curFilterArrayIdx >= 0 && m_curFilterArrayIdx < m_filter.size())
|
||||
emit applyCurentFilter(m_filter.at(m_curFilterArrayIdx));
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::maybeAddNewOverlay(qint64 curTime)
|
||||
{
|
||||
// more than one overlay can start at curTime
|
||||
while (true)
|
||||
{
|
||||
const int nextIdx = findNextIndex(curTime,
|
||||
m_curOverlayArrayIdx,
|
||||
m_overlays);
|
||||
if (nextIdx < 0)
|
||||
return;
|
||||
m_curOverlayArrayIdx = nextIdx;
|
||||
m_currentVisibleOverlays += m_overlays.at(nextIdx);
|
||||
DEBUG_LOG(m_logger) << "Showing new overlay with id " << m_overlays.at(m_curOverlayArrayIdx).overlayId
|
||||
<< " at time " << curTime;
|
||||
emit applyNewOverlay(m_overlays.at(m_curOverlayArrayIdx).overlayId);
|
||||
}
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::removeOutdatedOverlays(qint64 curTime)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " curTime = "<< curTime
|
||||
<< " m_currentVisibleOverlays.size()= "<< m_currentVisibleOverlays.size();
|
||||
|
||||
const qint64 curTimeRelative = curTime - m_replay.timeSpan.begin + m_replay.relativeTimeSpan.begin; // + m_replay.relativeTimeSpan.begin
|
||||
for (int i = m_currentVisibleOverlays.size() - 1; i >= 0; --i)
|
||||
{
|
||||
const qint64 endTime = m_currentVisibleOverlays.at(i).relativeTimeSpan.end;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " curTimeRelative = " << curTimeRelative << " endTime = " << endTime;
|
||||
|
||||
if (curTimeRelative > endTime)
|
||||
{
|
||||
emit removeOverlay(m_currentVisibleOverlays.at(i).overlayId);
|
||||
m_currentVisibleOverlays.removeAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainHandlerSqlite::replayTimeMaybeJumpedOverlays(qint64 curTime)
|
||||
{
|
||||
// not really optimal
|
||||
QSet<int> oldOverlayIds;
|
||||
oldOverlayIds.reserve(m_currentVisibleOverlays.size());
|
||||
for (const FilterInformation &overlay : qAsConst(m_currentVisibleOverlays))
|
||||
oldOverlayIds += overlay.overlayId;
|
||||
|
||||
m_curOverlayArrayIdx = -1;
|
||||
m_currentVisibleOverlays.clear();
|
||||
maybeAddNewOverlay(curTime);
|
||||
|
||||
for (const FilterInformation &overlay : qAsConst(m_currentVisibleOverlays))
|
||||
oldOverlayIds -= overlay.overlayId;
|
||||
for (const int overlayId : qAsConst(oldOverlayIds))
|
||||
emit removeOverlay(overlayId);
|
||||
}
|
||||
|
||||
// struct ReplayInformation
|
||||
// {
|
||||
// int id = 0;
|
||||
// TimeSpan timeSpan; // playbackTime msec since epoche
|
||||
// TimeSpan relativeTimeSpan; // timeInPresentation msec since begin SCRIPT
|
||||
|
||||
int MainHandlerSqlite::findNextIndex(qint64 curTime, int curIdx, const QVector<FilterInformation> &data) const
|
||||
{
|
||||
const int nextIdx = curIdx + 1;
|
||||
if (nextIdx < 0 || nextIdx >= data.size())
|
||||
return -1;
|
||||
const qint64 curTimeRelative = (curTime - m_replay.timeSpan.begin) + m_replay.relativeTimeSpan.begin;
|
||||
// ^abs ^absBgn cur Topic/Replay + timeInPresentation since begin SCRIPT
|
||||
// example: 1645787949000 - 1645787949000 + 375000
|
||||
|
||||
// startTime: msec, rel. to begin of SCRIPT
|
||||
const qint64 startTime = data.at(nextIdx).relativeTimeSpan.begin;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " curTimeRelative = " << curTimeRelative << " startTime = " << startTime;
|
||||
|
||||
if (curTimeRelative < startTime)
|
||||
return -1;
|
||||
return nextIdx;
|
||||
}
|
||||
|
||||
} // namespace SituationReplay
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* MainHandlerSqlite for AereaEffectSimulation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <memory>
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
#include <SituationReplay/srp_db.h>
|
||||
#include <SituationReplay/situationreplaysqlite_export.h>
|
||||
|
||||
namespace DDSConnector
|
||||
{
|
||||
class DdsConnector;
|
||||
}
|
||||
namespace NGLDB
|
||||
{
|
||||
template <typename DB> class DbServiceHandler;
|
||||
}
|
||||
|
||||
namespace FileManagement
|
||||
{
|
||||
namespace Database
|
||||
{
|
||||
struct FlmFileContent;
|
||||
}
|
||||
}
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
struct TimeSpan
|
||||
{
|
||||
qint64 begin = 0;
|
||||
qint64 end = 0;
|
||||
static SituationReplay::TimeSpan fromJson(const QJsonObject &obj)
|
||||
{
|
||||
SituationReplay::TimeSpan ts;
|
||||
ts.begin = qRound64(obj[QStringLiteral("start")].toDouble());
|
||||
ts.end = qRound64(obj[QStringLiteral("end")].toDouble());
|
||||
return ts;
|
||||
}
|
||||
QJsonObject toJson() const
|
||||
{
|
||||
return {
|
||||
{QStringLiteral("start"), begin},
|
||||
{QStringLiteral("end"), end},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct ReplayInformation
|
||||
{
|
||||
int id = 0;
|
||||
TimeSpan timeSpan; // playbackTime msec since epoche
|
||||
TimeSpan relativeTimeSpan; // timeInPresentation msec since begin SCRIPT
|
||||
QString databaseFilePath; // path to sqlite db
|
||||
QString replayConfigPath; // sitmap.json
|
||||
};
|
||||
|
||||
struct FilterInformation
|
||||
{
|
||||
int id = 0;
|
||||
int overlayId = 0;
|
||||
TimeSpan relativeTimeSpan;
|
||||
QJsonObject aesFilters;
|
||||
QJsonObject symbolSettings;
|
||||
QJsonObject buildingComponentSettings;
|
||||
QJsonObject mapSettings;
|
||||
};
|
||||
|
||||
class DbReader;
|
||||
class StaticPublisher;
|
||||
class HandlerSituationReplaySqlite;
|
||||
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
|
||||
|
||||
class SITUATIONREPLAYSQLITE_EXPORT MainHandlerSqlite final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainHandlerSqlite();
|
||||
~MainHandlerSqlite();
|
||||
|
||||
bool initDb(const ReplayInformation &replayInformation,
|
||||
const QVector<FilterInformation> &filter,
|
||||
const QVector<FilterInformation> &overlays);// first init dds needed!
|
||||
bool initDds(const ConnectionParams &output);
|
||||
|
||||
std::shared_ptr<HandlerSituationReplaySqlite> handlerSrp() const { return m_handlerSrp; }
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsReplay() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void initialReplaySpeed(double speed);
|
||||
void applyCurentFilter(const SituationReplay::FilterInformation &filter);
|
||||
void applyNewOverlay(int overlayId);
|
||||
void removeOverlay(int overlayId);
|
||||
void fileContentAvailable(const FileManagement::Database::FlmFileContent &data);
|
||||
private:
|
||||
bool initSrpHandler(int partitionIdIn, int partitionIdOut, qint64 beginTime, qint64 endTime);
|
||||
bool initStaticPublisher();
|
||||
bool loadReplayConfig(const QString &replayConfigPath);
|
||||
void maybeApplyNextFilter(qint64 curTime);
|
||||
void replayTimeMaybeJumpedFilter(qint64 curTime);
|
||||
void maybeAddNewOverlay(qint64 curTime);
|
||||
void removeOutdatedOverlays(qint64 curTime);
|
||||
void replayTimeMaybeJumpedOverlays(qint64 curTime);
|
||||
int findNextIndex(qint64 curTime, int curIdx, const QVector<FilterInformation> &data) const;
|
||||
private Q_SLOTS:
|
||||
void onReplayTimeChanged(qint64 curTime);
|
||||
void onReplayTimeMaybeJumped(qint64 curTime);
|
||||
|
||||
private:
|
||||
QVector<FilterInformation> m_filter;
|
||||
QVector<FilterInformation> m_overlays;
|
||||
QVector<FilterInformation> m_currentVisibleOverlays;
|
||||
ReplayInformation m_replay;
|
||||
int m_curFilterArrayIdx;
|
||||
int m_curOverlayArrayIdx;
|
||||
std::shared_ptr<HandlerSituationReplaySqlite> m_handlerSrp;
|
||||
std::unique_ptr<StaticPublisher> m_staticPublisher;
|
||||
std::shared_ptr<DdsHandler> m_ddsInterface;
|
||||
std::shared_ptr<DbHandler> m_dbHandler;
|
||||
std::shared_ptr<DbReader> m_dbReader;
|
||||
QSqlDatabase m_dbSqlite;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
} // namespace SituationReplay
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
* situation replay objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "object_situation_replay.h"
|
||||
#include "dds_handler.h"
|
||||
#include "db_reader.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
ObjectSituationReplay::ObjectSituationReplay(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<DbReader> &dbReader,
|
||||
int exerciseId)
|
||||
: m_ddsInterface(ddsHandler)
|
||||
, m_db(db)
|
||||
, m_dbReader(dbReader)
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_replayTimer(new QTimer(this))
|
||||
, m_currentReplayTime(0)
|
||||
, m_logger(getLogger("ObjectSituationReplay"))
|
||||
{
|
||||
connect(m_replayTimer, &QTimer::timeout, this, &ObjectSituationReplay::onReplayTimerTimeout);
|
||||
}
|
||||
|
||||
ObjectSituationReplay::~ObjectSituationReplay()
|
||||
{
|
||||
m_ddsInterface->dts()->removeSitReplayByKey(m_data.id);
|
||||
delete m_replayTimer;
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::isStopped() const
|
||||
{
|
||||
return (m_data.srpStateId == SituationReplay::SrpState_def::Stopped);
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::isRunning() const
|
||||
{
|
||||
return (m_data.srpStateId == SituationReplay::SrpState_def::Started ||
|
||||
m_data.srpStateId == SituationReplay::SrpState_def::Resumed);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ObjectSituationReplay::createObject(const Database::SrpSituationReplay &data)
|
||||
{
|
||||
static int s_idCounter = 1;
|
||||
m_data = data;
|
||||
setPace(m_data.pace);
|
||||
m_data.id = 0;
|
||||
m_data.srpStateId = SituationReplay::SrpState_def::Unknown;
|
||||
m_currentReplayTime = m_data.beginTime;
|
||||
if (m_db)
|
||||
{
|
||||
if (!m_db->insert(m_data))
|
||||
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting SrpSitatuationReplay-data into database"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data.id = s_idCounter++;
|
||||
}
|
||||
|
||||
// Id is serial -> will be generated by db => inside m_data after db-insert
|
||||
DEBUG_LOG(m_logger) << "New srpId: " << m_data.id;
|
||||
|
||||
switchToState(SituationReplay::SrpState_def::Stopped);
|
||||
|
||||
return Core::FunctionReplyObject(m_data.id);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ObjectSituationReplay::removeObject()
|
||||
{
|
||||
switchToState(SrpState::Stopped);
|
||||
|
||||
if (m_db && !m_db->removeSrpSituationReplay(m_data.id))
|
||||
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "SituationReplay %1 can not be removed")).arg(m_data.id);
|
||||
|
||||
m_ddsInterface->dts()->removeSitReplayByKey(m_data.id);
|
||||
|
||||
return Core::FunctionReplyObject(m_data.id);
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::setPace(double newPace)
|
||||
{
|
||||
if (newPace < 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Trying to set a pace < 0";
|
||||
return false;
|
||||
}
|
||||
m_data.pace = newPace;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ObjectSituationReplay::setSrpData(const Database::SrpSituationReplay &newData)
|
||||
{
|
||||
const int id = m_data.id;
|
||||
m_data = newData;
|
||||
setPace(m_data.pace);
|
||||
m_data.srpStateId = SituationReplay::SrpState::Unknown;
|
||||
m_data.id = id;
|
||||
m_currentReplayTime = m_data.beginTime;
|
||||
|
||||
switchToState(newData.srpStateId);
|
||||
|
||||
if (m_db)
|
||||
{
|
||||
if (!m_db->update(m_data))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error updating SitReplay data in database (exerciseState)";
|
||||
return false;
|
||||
}
|
||||
|
||||
Database::SrpReplayJournal stateChange;
|
||||
|
||||
stateChange.situationReplayId = m_data.id;
|
||||
stateChange.beginTime = m_data.beginTime;
|
||||
stateChange.endTime = m_data.endTime;
|
||||
stateChange.pace = m_data.pace;
|
||||
stateChange.replayPartitionId = m_data.replayPartitionId;
|
||||
stateChange.srpStateId = m_data.srpStateId;
|
||||
stateChange.changedAt = QDateTime::currentDateTime();
|
||||
|
||||
// record SrpStateChange
|
||||
if (!m_db->insert(stateChange))
|
||||
WARNING_LOG(m_logger) << "Recording change of srpState failed";
|
||||
}
|
||||
|
||||
// Publish Data via DTS
|
||||
onPublishReplayInformation();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::start()
|
||||
{
|
||||
INFO_LOG(m_logger) << "start: " << m_currentReplayTime;
|
||||
m_currentReplayTime = m_data.beginTime;
|
||||
|
||||
emit started(m_currentReplayTime);
|
||||
|
||||
// Read all data for a certain interval
|
||||
if (!m_dbReader->setReplayStartTime(m_currentReplayTime))
|
||||
return false;
|
||||
if (!checkPublishData())
|
||||
return false;
|
||||
m_replayTimer->start(1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::pause()
|
||||
{
|
||||
INFO_LOG(m_logger) << "paused: " << m_currentReplayTime;
|
||||
m_replayTimer->stop();
|
||||
emit paused();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::resume()
|
||||
{
|
||||
INFO_LOG(m_logger) << "resumed" << m_currentReplayTime;
|
||||
m_replayTimer->start(1000);
|
||||
emit resumed(m_currentReplayTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::stop()
|
||||
{
|
||||
INFO_LOG(m_logger) << "stopped: " << m_currentReplayTime;
|
||||
m_replayTimer->stop();
|
||||
emit stopped();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectSituationReplay::onPublishReplayInformation()
|
||||
{
|
||||
const SituationReplay::SitReplay ddsData(m_data.id,
|
||||
m_data.srpStateId,
|
||||
m_exerciseId,
|
||||
m_data.replayPartitionId,
|
||||
m_data.beginTime,
|
||||
m_data.endTime,
|
||||
m_data.pace);
|
||||
|
||||
INFO_LOG(m_logger) << "Publish SitReplay data: " << ddsData;
|
||||
|
||||
if (!m_ddsInterface->dts()->publish(ddsData))
|
||||
ERROR_LOG(m_logger) << "Error publishing SitReplay data to dds";
|
||||
}
|
||||
|
||||
void ObjectSituationReplay::onPublishReplayTime()
|
||||
{
|
||||
// publish partitionTime
|
||||
m_ddsInterface->publishPartitionTime(Core::PartitionTime(m_currentReplayTime));
|
||||
emit replayTimeChanged(m_currentReplayTime);
|
||||
}
|
||||
|
||||
void ObjectSituationReplay::onReplayTimerTimeout()
|
||||
{
|
||||
m_currentReplayTime += qRound64(m_data.pace * 1000);
|
||||
DEBUG_LOG(m_logger) << "onReplayTimerTimeout, endTime: " << m_data.endTime << " - " << m_currentReplayTime;
|
||||
checkPublishData();
|
||||
}
|
||||
|
||||
bool ObjectSituationReplay::checkPublishData()
|
||||
{
|
||||
INFO_LOG(m_logger) << " checkPublishData...";
|
||||
|
||||
onPublishReplayTime();
|
||||
if (m_data.endTime != 0 && m_data.endTime < m_currentReplayTime)
|
||||
{
|
||||
if (switchToState(SrpState_def::Stopped).error())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QElapsedTimer timer; if (m_logger.isInfoEnabled()) timer.start();
|
||||
|
||||
// publish data for current time
|
||||
m_dbReader->publish(m_currentReplayTime);
|
||||
|
||||
if (m_logger.isInfoEnabled()) INFO_LOG(m_logger) << "m_dbReader->publish took " << timer.elapsed() << " [ms]";
|
||||
|
||||
|
||||
if (qFuzzyIsNull(m_data.pace)) // pace == 0 -> snapshot
|
||||
{
|
||||
QElapsedTimer timerReadData; if (m_logger.isInfoEnabled()) timerReadData.start();
|
||||
|
||||
m_dbReader->waitForAsyncOperations(m_data.endTime);
|
||||
if (switchToState(SrpState_def::Stopped).error())
|
||||
return false;
|
||||
|
||||
if (m_logger.isInfoEnabled()) INFO_LOG(m_logger) << "m_dbReader->waitForAsyncOperations took " << timerReadData.elapsed() << " [ms]";
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
QElapsedTimer timerReadData; if (m_logger.isInfoEnabled()) timerReadData.start();
|
||||
|
||||
// read next chunk
|
||||
if (!m_dbReader->readData(m_currentReplayTime, m_currentReplayTime + qRound64(m_data.pace * 1000)))
|
||||
return false;
|
||||
|
||||
if (m_logger.isInfoEnabled()) INFO_LOG(m_logger) << "m_dbReader->readData took " << timerReadData.elapsed() << " [ms]";
|
||||
}
|
||||
}
|
||||
INFO_LOG(m_logger) << " checkPublishData... DONE";
|
||||
return true;
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject ObjectSituationReplay::switchToState(SrpState newSrpState)
|
||||
{
|
||||
Core::FunctionReplyObject ret(m_data.id);
|
||||
INFO_LOG(m_logger) << "-------------- switchTo: " << newSrpState
|
||||
<< ", current: " << m_data.srpStateId;
|
||||
if (m_data.srpStateId != newSrpState)
|
||||
{
|
||||
switch (newSrpState.underlying())
|
||||
{
|
||||
case SrpState_def::Paused:
|
||||
if (!pause())
|
||||
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not pause replay"));
|
||||
break;
|
||||
case SrpState_def::Resumed:
|
||||
if (!resume())
|
||||
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not resume replay"));
|
||||
break;
|
||||
case SrpState_def::Started:
|
||||
if (!start())
|
||||
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not start replay"));
|
||||
break;
|
||||
case SrpState_def::Stopped:
|
||||
if (!stop())
|
||||
return Core::FunctionReplyObject(m_data.id, tr_lts("dds", "Could not stop replay"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_data.srpStateId = newSrpState;
|
||||
onPublishReplayInformation();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // Namespace SituationReplay
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* situation replay objects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include "dds_handler.h"
|
||||
#include "db_reader.h"
|
||||
#include <DDS/Core/function_reply_object.h>
|
||||
|
||||
// Generated
|
||||
#include <SituationReplay/srp_db.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class DatabaseInterface;
|
||||
class DbReader;
|
||||
|
||||
class ObjectSituationReplay : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ObjectSituationReplay(const std::shared_ptr<DdsHandler> &ddsHandler,
|
||||
const std::shared_ptr<DatabaseInterface> &db,
|
||||
const std::shared_ptr<DbReader> &dbReader,
|
||||
int exerciseId);
|
||||
~ObjectSituationReplay();
|
||||
|
||||
Core::FunctionReplyObject createObject(const Database::SrpSituationReplay &data);
|
||||
Core::FunctionReplyObject removeObject();
|
||||
|
||||
qint32 getId() const { return m_data.id; }
|
||||
qint32 getExerciseId() const { return m_exerciseId; }
|
||||
qint32 getReplayPartitionId() const { return m_data.replayPartitionId; }
|
||||
qint64 currentReplayTime() const { return m_currentReplayTime; }
|
||||
|
||||
SrpState srpState() const { return m_data.srpStateId; }
|
||||
double pace() const { return m_data.pace; }
|
||||
bool setPace(double newPace);
|
||||
|
||||
// Used by SrpStateManager (only internal)
|
||||
bool setSrpData(const Database::SrpSituationReplay &newData);
|
||||
|
||||
// Used by Client
|
||||
Core::FunctionReplyObject switchToState(SrpState newSrpState);
|
||||
|
||||
bool isRunning() const;
|
||||
bool isStopped() const;
|
||||
|
||||
bool start();
|
||||
bool pause();
|
||||
bool resume();
|
||||
bool stop();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onPublishReplayInformation();
|
||||
void onPublishReplayTime();
|
||||
void onReplayTimerTimeout();
|
||||
|
||||
private:
|
||||
bool checkPublishData();
|
||||
|
||||
Q_SIGNALS:
|
||||
// for thp
|
||||
void replayTimeChanged(qint64 currentReplayTime);
|
||||
void started(qint64 currentReplayTime);
|
||||
void paused();
|
||||
void resumed(qint64 currentReplayTime);
|
||||
void stopped();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsInterface;
|
||||
std::shared_ptr<DatabaseInterface> m_db;
|
||||
std::shared_ptr<DbReader> m_dbReader;
|
||||
Database::SrpSituationReplay m_data;
|
||||
int m_exerciseId;
|
||||
QTimer *m_replayTimer;
|
||||
qint64 m_currentReplayTime;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Settings for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
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 SituationReplay
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Settings for SituationReplay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
//!< The real NGL::Settings - object
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
}
|
||||
|
||||
} // namespace SituationReplay
|
||||
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 SRP_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define SRP_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCSRPCOMMON_LIB)
|
||||
# define SRP_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define SRP_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SRP_CLIENT_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define SRP_CLIENT_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCSRPCLIENT_LIB)
|
||||
# define SRP_CLIENT_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define SRP_CLIENT_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SRP_SERVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define SRP_SERVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCSRPSERVER_LIB)
|
||||
# define SRP_SERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define SRP_SERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="SituationReplay" abbreviation="SRP" procNames="SituationReplay" exerciseDependency="Exercise">
|
||||
<rcs>
|
||||
<Id Id="$Id$"/>
|
||||
<HeadURL HeadURL="$HeadURL$"/>
|
||||
<Author Author="$Author$"/>
|
||||
</rcs>
|
||||
<tables>
|
||||
<table name="srp_replay_journal" comment="Information about past and currently used situation replay(as a journal)">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="situation_replay_id" datatype="integer"/>
|
||||
<column name="replay_partition_id" datatype="integer"/>
|
||||
<column name="srp_state_id" datatype="integer" isForeignKey="1"/>
|
||||
<column name="begin_time" datatype="bigint"/>
|
||||
<column name="end_time" datatype="bigint"/>
|
||||
<column name="changed_at" datatype="timestamp"/>
|
||||
<column name="pace" datatype="real"/>
|
||||
<foreignKey name="FK_srp_journal_srp_state">
|
||||
<source table="srp_replay_journal" column="srp_state_id"/>
|
||||
<destination table="srp_state" column="id"/>
|
||||
</foreignKey>
|
||||
</table>
|
||||
<table name="srp_situation_replay">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1">
|
||||
<sequence start="1" increment="1"/>
|
||||
</column>
|
||||
<column name="srp_state_id" datatype="integer" isForeignKey="1"/>
|
||||
<column name="replay_partition_id" datatype="integer"/>
|
||||
<column name="begin_time" datatype="bigint"/>
|
||||
<column name="end_time" datatype="bigint"/>
|
||||
<column name="pace" datatype="real"/>
|
||||
<foreignKey name="FK_srp_situation_replay_srp_state">
|
||||
<source table="srp_situation_replay" column="srp_state_id"/>
|
||||
<destination table="srp_state" column="id"/>
|
||||
</foreignKey>
|
||||
</table>
|
||||
<table name="srp_state">
|
||||
<column name="id" datatype="integer" isPrimaryKey="1"/>
|
||||
<column name="name" datatype="text"/>
|
||||
</table>
|
||||
</tables>
|
||||
<views/>
|
||||
<dbServiceStructs>
|
||||
<serviceStruct name="SrpReplayJournal" table="srp_replay_journal"/>
|
||||
<serviceStruct name="SrpSituationReplay" table="srp_situation_replay"/>
|
||||
<table name="srp_replay_journal"/>
|
||||
<table name="srp_situation_replay"/>
|
||||
</dbServiceStructs>
|
||||
<topicTypes>
|
||||
<topicType name="ChangeReplayStateRequest">
|
||||
<column name="id" idlType="long"/>
|
||||
<column name="state" idlType="SrpState"/>
|
||||
<column name="replayPartitionId" idlType="long"/>
|
||||
<column name="beginTime" idlType="long long"/>
|
||||
<column name="endTime" idlType="long long"/>
|
||||
<column name="pace" idlType="double" isOptional="1"/>
|
||||
</topicType>
|
||||
<topicType name="SitReplay" extensibility="EXTENSIBLE" isDataObject="1" routeToClient="1" routeToServer="0" routeInReplay="0">
|
||||
<column name="id" idlType="long" isKey="1"/>
|
||||
<column name="state" idlType="SrpState"/>
|
||||
<column name="exerciseId" idlType="long" comment="Only in idl-struct, not needed in table"/>
|
||||
<column name="replayPartitionId" idlType="long"/>
|
||||
<column name="beginTime" idlType="long long"/>
|
||||
<column name="endTime" idlType="long long"/>
|
||||
<column name="pace" idlType="double"/>
|
||||
</topicType>
|
||||
</topicTypes>
|
||||
<functionTopics>
|
||||
<functionTopic name="ChangeReplayState" requestTopicType="ChangeReplayStateRequest" replyTopicType="Core::FunctionReply" requestTopicName="ChangeReplayStateRequest" replyTopicName="ChangeReplayStateReply" routeInReplay="0"/>
|
||||
</functionTopics>
|
||||
<enumerations>
|
||||
<enumeration name="SrpState" table="srp_state">
|
||||
<attribute key="Unknown" value="0"/>
|
||||
<attribute key="Started" value="1"/>
|
||||
<attribute key="Paused" value="2"/>
|
||||
<attribute key="Resumed" value="3"/>
|
||||
<attribute key="Stopped" value="4"/>
|
||||
</enumeration>
|
||||
</enumerations>
|
||||
<operatorRights offset="36"/>
|
||||
</service>
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
* Publish static data (pdm, asm, ism) for THP
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
|
||||
#include "static_publisher.h"
|
||||
#include <QCryptographicHash>
|
||||
#include <QJsonDocument>
|
||||
#include <QTimer>
|
||||
|
||||
#include <DDS/DTS/generic_dts_impl.h>
|
||||
|
||||
#include <AssetManagement/asm_db.h>
|
||||
#include <AssetManagement/convert_db_to_dds.h>
|
||||
#include <ExerciseManagement/exm_db.h>
|
||||
#include <ExerciseManagement/convert_db_to_dds.h>
|
||||
#include <FileManagement/flm_db.h>
|
||||
#include <FileManagement/convert_db_to_dds.h>
|
||||
#include <InfrastructureManagement/ism_db.h>
|
||||
#include <InfrastructureManagement/convert_db_to_dds.h>
|
||||
#include <ParticipantManagement/ppm_db.h>
|
||||
#include <ParticipantManagement/convert_db_to_dds.h>
|
||||
#include <ProjectDataManagement/pdm_db.h>
|
||||
#include <ProjectDataManagement/convert_db_to_dds.h>
|
||||
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
StaticPublisher::StaticPublisher(const std::shared_ptr<DdsHandler> &ddsInterface,
|
||||
const QSqlDatabase &db)
|
||||
: m_ddsInterface(ddsInterface)
|
||||
, m_db(db)
|
||||
{
|
||||
auto ddsConnector = ddsInterface->ddsReplay();
|
||||
m_asmTrainingArea.reset(ddsConnector->createDTS<DTS::TrainingAreaImpl>());
|
||||
m_exmExercise.reset(ddsConnector->createDTS<DTS::ExerciseImpl>());
|
||||
m_exmExercisePhase.reset(ddsConnector->createDTS<DTS::ExercisePhaseImpl>());
|
||||
m_flmFileContent.reset(ddsConnector->createDTS<DTS::FileContentImpl>());
|
||||
m_flmFileTypeInfo.reset(ddsConnector->createDTS<DTS::FileTypeInfoImpl>());
|
||||
m_flmFolder.reset(ddsConnector->createDTS<DTS::FolderImpl>());
|
||||
|
||||
m_ismMainFootprint.reset(ddsConnector->createDTS<DTS::MainFootprintImpl>());
|
||||
m_ismMainStructureElement.reset(ddsConnector->createDTS<DTS::MainStructureElementImpl>());
|
||||
|
||||
m_ppmType.reset(ddsConnector->createDTS<DTS::TypeImpl>());
|
||||
|
||||
m_pdmCanComponentString.reset(ddsConnector->createDTS<DTS::CanComponentStringImpl>());
|
||||
m_pdmChargeType.reset(ddsConnector->createDTS<DTS::ChargeTypeImpl>());
|
||||
m_pdmFirePurpose.reset(ddsConnector->createDTS<DTS::FirePurposeImpl>());
|
||||
m_pdmGearType.reset(ddsConnector->createDTS<DTS::GearTypeImpl>());
|
||||
m_ppmGearTypeChargeType.reset(ddsConnector->createDTS<DTS::GearTypeChargeTypeImpl>());
|
||||
m_pdmIgniterType.reset(ddsConnector->createDTS<DTS::IgniterTypeImpl>());
|
||||
m_pdmIgniterFunction.reset(ddsConnector->createDTS<DTS::IgniterFunctionImpl>());
|
||||
m_pdmChargeTypeIgniterTypeIgniterFunction.reset(ddsConnector->createDTS<DTS::ChargeTypeIgniterTypeIgniterFunctionImpl>());
|
||||
m_pdmLoadType.reset(ddsConnector->createDTS<DTS::LoadTypeImpl>());
|
||||
m_pdmChargeTypeLoadType.reset(ddsConnector->createDTS<DTS::ChargeTypeLoadTypeImpl>());
|
||||
|
||||
m_pdmLanguageHmi.reset(ddsConnector->createDTS<DTS::LanguageHmiImpl>());
|
||||
m_pdmTranslationBlob.reset(ddsConnector->createDTS<DTS::TranslationBlobImpl>());
|
||||
m_pdmVulnerabilityKind.reset(ddsConnector->createDTS<DTS::VulnerabilityKindImpl>());
|
||||
|
||||
QTimer::singleShot(0, this, &StaticPublisher::publishData);
|
||||
}
|
||||
|
||||
StaticPublisher::~StaticPublisher()
|
||||
{
|
||||
m_asmTrainingArea = nullptr;
|
||||
m_exmExercise = nullptr;
|
||||
m_exmExercisePhase = nullptr;
|
||||
m_flmFileContent = nullptr;
|
||||
m_flmFileTypeInfo = nullptr;
|
||||
m_flmFolder = nullptr;
|
||||
|
||||
m_ismMainFootprint = nullptr;
|
||||
m_ismMainStructureElement = nullptr;
|
||||
|
||||
m_ppmType = nullptr;
|
||||
|
||||
m_pdmCanComponentString = nullptr;
|
||||
m_pdmChargeType = nullptr;
|
||||
m_pdmFirePurpose = nullptr;
|
||||
m_pdmGearType = nullptr;
|
||||
m_ppmGearTypeChargeType = nullptr;
|
||||
m_pdmIgniterType = nullptr;
|
||||
m_pdmIgniterFunction = nullptr;
|
||||
m_pdmLoadType = nullptr;
|
||||
m_pdmChargeTypeIgniterTypeIgniterFunction = nullptr;
|
||||
m_pdmChargeTypeLoadType = nullptr;
|
||||
m_pdmLanguageHmi = nullptr;
|
||||
m_pdmTranslationBlob = nullptr;
|
||||
m_pdmVulnerabilityKind = nullptr;
|
||||
|
||||
m_ddsInterface = nullptr;
|
||||
}
|
||||
|
||||
void StaticPublisher::publishData()
|
||||
{
|
||||
{
|
||||
auto db = AssetManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
db->select([this](const AssetManagement::Database::AsmTrainingArea &data) { m_asmTrainingArea->write(AssetManagement::Database::convert(data)); });
|
||||
}
|
||||
{
|
||||
auto db = ExerciseManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
db->select([this](const ExerciseManagement::Database::ExmExercise &data) { m_exmExercise->write(ExerciseManagement::Database::convert(data)); });
|
||||
db->select([this](const ExerciseManagement::Database::ExmExercisePhase &data) { m_exmExercisePhase->write(ExerciseManagement::Database::convert(data)); });
|
||||
}
|
||||
{
|
||||
auto db = FileManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
db->select([this](const FileManagement::Database::FlmFileContent &data) { m_flmFileContent->write(FileManagement::Database::convert(data)); emit fileContentAvailable(data); });
|
||||
db->select([this](const FileManagement::Database::FlmFileTypeInfo &data) { m_flmFileTypeInfo->write(FileManagement::Database::convert(data)); });
|
||||
db->select([this](const FileManagement::Database::FlmFolder &data) { m_flmFolder->write(FileManagement::Database::convert(data)); });
|
||||
}
|
||||
{
|
||||
auto db = InfrastructureManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
publishMainStructureElement(db);
|
||||
}
|
||||
{
|
||||
auto db = ParticipantManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
db->select([this](const ParticipantManagement::Database::PpmType &data) { m_ppmType->write(ParticipantManagement::Database::convert(data)); });
|
||||
}
|
||||
{
|
||||
auto db = ProjectDataManagement::DatabaseInterface::create(0);
|
||||
db->init(m_db);
|
||||
db->select([this](const ProjectDataManagement::Database::PdmCanComponentString &data) { m_pdmCanComponentString->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmChargeType &data) { m_pdmChargeType->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmFirePurpose &data) { m_pdmFirePurpose->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmGearType &data) { m_pdmGearType->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmGearTypeChargeType &data) { m_ppmGearTypeChargeType->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmIgniterType &data) { m_pdmIgniterType->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmIgniterFunction &data) { m_pdmIgniterFunction->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmChargeTypeIgniterTypeIgniterFunction &data) { m_pdmChargeTypeIgniterTypeIgniterFunction->write(ProjectDataManagement::Database::convert(data)); });
|
||||
db->select([this](const ProjectDataManagement::Database::PdmLanguage &data) { m_pdmLanguageHmi->write(ProjectDataManagement::Database::convert(data)); });
|
||||
publishTranslationBlob(db);
|
||||
db->select([this](const ProjectDataManagement::Database::PdmVulnerabilityKind &data) { m_pdmVulnerabilityKind->write(ProjectDataManagement::Database::convert(data)); });
|
||||
}
|
||||
m_db = QSqlDatabase();
|
||||
}
|
||||
|
||||
void StaticPublisher::publishMainStructureElement(const std::shared_ptr<InfrastructureManagement::DatabaseInterface> &db)
|
||||
{
|
||||
// read all MSE from database
|
||||
QHash<qint64, InfrastructureManagement::Database::IsmMainStructureElement> mainStructureElements;
|
||||
if (!db->select([&mainStructureElements] (const InfrastructureManagement::Database::IsmMainStructureElement &data) { mainStructureElements[data.id] = data;}))
|
||||
return;
|
||||
|
||||
// read all SE from database
|
||||
QHash<qint64, QVector<InfrastructureManagement::Database::IsmStructureElement>> structureElements;
|
||||
if (!db->select([&structureElements](const InfrastructureManagement::Database::IsmStructureElement &data) { structureElements[data.mainStructureElementId].push_back(data);}))
|
||||
return;
|
||||
|
||||
QHash<qint64, qint64> seId2mseId;
|
||||
for (const auto &mse : qAsConst(mainStructureElements))
|
||||
{
|
||||
auto mseDds = InfrastructureManagement::Database::convert(mse);
|
||||
auto itContSe = structureElements.constFind(mse.id);
|
||||
if (itContSe == structureElements.constEnd())
|
||||
continue;
|
||||
for (const auto &se : itContSe.value())
|
||||
{
|
||||
// currently only the building, not floors, rooms or mounting points needed
|
||||
// DEDÖÖM we need rooms and floors and every thing else!
|
||||
//if (se.structureElementTypeId != InfrastructureManagement::StructureElementType_def::Building)
|
||||
// continue;
|
||||
mseDds.elements().push_back(InfrastructureManagement::Database::convert(se));
|
||||
seId2mseId[se.id] = mseDds.id();
|
||||
// break;
|
||||
}
|
||||
if (mseDds.elements().size() > 0)
|
||||
m_ismMainStructureElement->write(mseDds);
|
||||
}
|
||||
|
||||
QHash<int, QMap<int, InfrastructureManagement::Database::IsmStructureElementFootprint>> footprintSorted;
|
||||
auto cb = [&footprintSorted](const InfrastructureManagement::Database::IsmStructureElementFootprint &fp)
|
||||
{
|
||||
footprintSorted[fp.structureElementId][fp.indexNo] = fp;
|
||||
};
|
||||
|
||||
if (!db->select(cb))
|
||||
return;
|
||||
|
||||
InfrastructureManagement::MainFootprint mf;
|
||||
InfrastructureManagement::FootprintElement elem;
|
||||
for (const QMap<int, InfrastructureManagement::Database::IsmStructureElementFootprint> &cont : qAsConst(footprintSorted))
|
||||
{
|
||||
if (cont.empty())
|
||||
continue;
|
||||
const int structureElementId = cont.first().structureElementId;
|
||||
const int mainStructureElementId = seId2mseId.value(structureElementId);
|
||||
if (!mainStructureElementId)
|
||||
continue;
|
||||
|
||||
mf.id(mainStructureElementId);
|
||||
mf.structureElementId(structureElementId);
|
||||
mf.name(mainStructureElements.value(mainStructureElementId).name.toStdString());
|
||||
mf.elements().clear();
|
||||
mf.elements().reserve(cont.size());
|
||||
for (const auto &pos : cont)
|
||||
{
|
||||
elem.id(pos.id);
|
||||
elem.relPosition(Core::RelativePosition(pos.relPosition.x(),
|
||||
pos.relPosition.y(),
|
||||
pos.relPosition.z()));
|
||||
mf.elements().push_back(elem);
|
||||
}
|
||||
m_ismMainFootprint->write(mf);
|
||||
}
|
||||
}
|
||||
|
||||
void StaticPublisher::publishTranslationBlob(const std::shared_ptr<ProjectDataManagement::DatabaseInterface> &db)
|
||||
{
|
||||
QJsonArray arr;
|
||||
const auto cb = [&arr](const ProjectDataManagement::Database::PdmTranslation &data)
|
||||
{
|
||||
arr += QJsonObject({{QStringLiteral("isoCode"), data.isoCode},
|
||||
{QStringLiteral("context"), data.context},
|
||||
{QStringLiteral("key"), data.key},
|
||||
{QStringLiteral("disambiguation"), data.disambiguation},
|
||||
{QStringLiteral("translation"), data.translation}
|
||||
});
|
||||
};
|
||||
|
||||
if (!db->select(cb))
|
||||
return;
|
||||
|
||||
const QJsonObject jObj{ {QStringLiteral("translations"), arr} };
|
||||
const QByteArray data = QJsonDocument(jObj).toBinaryData();
|
||||
const QByteArray compressed = qCompress(data, 9);
|
||||
const QByteArray md5Sum = QCryptographicHash::hash(compressed, QCryptographicHash::Md5).toHex();
|
||||
|
||||
m_pdmTranslationBlob->write(ProjectDataManagement::TranslationBlob(
|
||||
1,
|
||||
LtsUtils::convert<std::vector<uint8_t>>(compressed),
|
||||
md5Sum.data()));
|
||||
}
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Publish static data (pdm, asm, ism) for THP
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2016-01-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include <QSqlDatabase>
|
||||
#include <QObject>
|
||||
#include <AssetManagement/asm_dts_types.h>
|
||||
#include <ExerciseManagement/exm_dts_types.h>
|
||||
#include <FileManagement/flm_dts_types.h>
|
||||
#include <InfrastructureManagement/ism_dts_types.h>
|
||||
#include <ParticipantManagement/ppm_dts_types.h>
|
||||
#include <ProjectDataManagement/pdm_dts_types.h>
|
||||
|
||||
namespace FileManagement
|
||||
{
|
||||
namespace Database
|
||||
{
|
||||
struct FlmFileContent;
|
||||
}
|
||||
}
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class DatabaseInterface;
|
||||
}
|
||||
namespace ProjectDataManagement
|
||||
{
|
||||
class DatabaseInterface;
|
||||
}
|
||||
|
||||
namespace SituationReplay
|
||||
{
|
||||
class StaticPublisher final : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StaticPublisher(const std::shared_ptr<DdsHandler> &ddsInterface,
|
||||
const QSqlDatabase &db);
|
||||
|
||||
~StaticPublisher();
|
||||
Q_SIGNALS:
|
||||
void fileContentAvailable(const FileManagement::Database::FlmFileContent &data);
|
||||
private:
|
||||
void publishData();
|
||||
// including footprint
|
||||
void publishMainStructureElement(const std::shared_ptr<InfrastructureManagement::DatabaseInterface> &db);
|
||||
void publishTranslationBlob(const std::shared_ptr<ProjectDataManagement::DatabaseInterface> &db);
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsInterface;
|
||||
std::unique_ptr<DTS::TrainingArea> m_asmTrainingArea;
|
||||
std::unique_ptr<DTS::Exercise> m_exmExercise;
|
||||
std::unique_ptr<DTS::ExercisePhase> m_exmExercisePhase;
|
||||
std::unique_ptr<DTS::FileContent> m_flmFileContent;
|
||||
std::unique_ptr<DTS::FileTypeInfo> m_flmFileTypeInfo;
|
||||
std::unique_ptr<DTS::Folder> m_flmFolder;
|
||||
std::unique_ptr<DTS::MainFootprint> m_ismMainFootprint;
|
||||
std::unique_ptr<DTS::MainStructureElement> m_ismMainStructureElement;
|
||||
std::unique_ptr<DTS::Type> m_ppmType;
|
||||
std::unique_ptr<DTS::CanComponentString> m_pdmCanComponentString;
|
||||
std::unique_ptr<DTS::ChargeType> m_pdmChargeType;
|
||||
std::unique_ptr<DTS::FirePurpose> m_pdmFirePurpose;
|
||||
std::unique_ptr<DTS::GearType> m_pdmGearType;
|
||||
std::unique_ptr<DTS::GearTypeChargeType> m_ppmGearTypeChargeType;
|
||||
std::unique_ptr<DTS::IgniterType> m_pdmIgniterType;
|
||||
std::unique_ptr<DTS::IgniterFunction> m_pdmIgniterFunction;
|
||||
std::unique_ptr<DTS::LoadType> m_pdmLoadType;
|
||||
std::unique_ptr<DTS::ChargeTypeIgniterTypeIgniterFunction> m_pdmChargeTypeIgniterTypeIgniterFunction;
|
||||
std::unique_ptr<DTS::ChargeTypeLoadType> m_pdmChargeTypeLoadType;
|
||||
std::unique_ptr<DTS::LanguageHmi> m_pdmLanguageHmi;
|
||||
std::unique_ptr<DTS::TranslationBlob> m_pdmTranslationBlob;
|
||||
std::unique_ptr<DTS::VulnerabilityKind> m_pdmVulnerabilityKind;
|
||||
QSqlDatabase m_db;
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user