Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+67
@@ -0,0 +1,67 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(xml_FILE rsc_service.xml)
|
||||
|
||||
SET(SRCS_lib
|
||||
logger.cpp
|
||||
logger.h
|
||||
connection.cpp
|
||||
connection.h
|
||||
data_writer_task.cpp
|
||||
data_writer_task.h
|
||||
session.cpp
|
||||
session.h
|
||||
session_handler.cpp
|
||||
session_handler.h
|
||||
)
|
||||
NGL_ADD_LIBRARY2(WS AAR SV rscCommon SHARED ${SRCS_lib})
|
||||
NGL_TARGET_LINK_LIBRARIES(rscCommon
|
||||
PRIVATE
|
||||
LtsPluginLoader
|
||||
PUBLIC
|
||||
ddsconnector
|
||||
NGLLogger
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
## currently no ruting service in guez
|
||||
#IF (NOT GUEZ_MODE)#
|
||||
|
||||
#SET(SRCS_exe
|
||||
# main_handler.cpp
|
||||
# main_handler.h
|
||||
# main.cpp
|
||||
# partition_handler.cpp
|
||||
# partition_handler.h
|
||||
#)
|
||||
# make sure xml file is properly installed
|
||||
#CODEGEN_HANDLE_SVC_XML(SRCS_exe ${xml_FILE})
|
||||
|
||||
#NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
#NGL_ADD_EXECUTABLE(AAR SV svcRoutingServiceNG ${SRCS_exe})
|
||||
#NGL_TARGET_LINK_LIBRARIES(svcRoutingServiceNG
|
||||
# rscCommon
|
||||
# Qt5::Core
|
||||
# ddsgen
|
||||
# ddsconnector
|
||||
# RTI::nddsc
|
||||
# RTI::nddscore
|
||||
# RTI::nddscpp2
|
||||
# LtsCommandLineParser
|
||||
# NGLLogger
|
||||
# nglcoreapplication
|
||||
# routing_plugin#
|
||||
|
||||
# ddscore
|
||||
# svcCoreClient
|
||||
# svcExmClient
|
||||
#)
|
||||
#NGL_INSTALL_TARGET(svcRoutingServiceNG)
|
||||
#NGL_INSTALL(AAR SV FILES log4cxx_rsc.props DESTINATION bin)
|
||||
#NGL_ADD_TARGET_LINK(svcRoutingServiceNG sRSC)
|
||||
|
||||
#ENDIF()
|
||||
Executable
+188
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main connection handling
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
|
||||
#include "connection.h"
|
||||
#include "data_writer_task.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <DDS/DDSConnector/publisher.h>
|
||||
#include <DDS/DDSConnector/subscriber.h>
|
||||
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
Connection::Connection(const dds::domain::DomainParticipant &domainParticipant,
|
||||
const std::string &partition,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRoute,
|
||||
const std::string &desc)
|
||||
: m_output(nullptr)
|
||||
, m_domainParticipant(domainParticipant)
|
||||
, m_publisher(new DDSConnector::Publisher(domainParticipant, partition))
|
||||
, m_subscriber(new DDSConnector::Subscriber(domainParticipant, partition, false))
|
||||
, m_dataWriterTask(nullptr)
|
||||
, m_topicsToRoute(topicsToRoute)
|
||||
, m_partition(partition)
|
||||
, m_description(desc)
|
||||
, m_logger(getLogger("Connection"))
|
||||
{
|
||||
INFO_LOG(m_logger) << "Create connection: " << partition
|
||||
<< ", domain: " << domainParticipant.domain_id()
|
||||
<< ", direction: " << m_description
|
||||
<< " (" << this << ")";
|
||||
}
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
setOutput(nullptr);
|
||||
shutdown();
|
||||
try
|
||||
{
|
||||
if (m_subscriber)
|
||||
m_subscriber->getDdsSubscriber().close();
|
||||
}
|
||||
catch (const dds::core::Exception &ex)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "sub close ex: " << ex.what();
|
||||
}
|
||||
m_subscriber = nullptr;
|
||||
try
|
||||
{
|
||||
if (m_publisher)
|
||||
m_publisher->getDdsPublisher().close();
|
||||
}
|
||||
catch (const dds::core::Exception &ex)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "pub close ex: " << ex.what();
|
||||
}
|
||||
m_publisher = nullptr;
|
||||
m_domainParticipant = nullptr;
|
||||
}
|
||||
|
||||
void Connection::setOutput(Connection *output)
|
||||
{
|
||||
if (m_output == output)
|
||||
return;
|
||||
|
||||
m_output = output;
|
||||
}
|
||||
|
||||
bool Connection::initialize()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "initialize new connection for " << m_partition
|
||||
<< ", direction: " << m_description
|
||||
<< " (" << this << ")";
|
||||
|
||||
if (m_writerThread.valid())
|
||||
shutdown();
|
||||
|
||||
m_dataWriterTask.reset(new DataWriterTask);
|
||||
|
||||
if (!m_output)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing connection for " << m_partition
|
||||
<< ", direction: " << m_description << " - no output set!";
|
||||
return false;
|
||||
}
|
||||
m_writerThread = std::async(std::launch::async, [this]() { this->m_dataWriterTask->writeSamples();});
|
||||
return initTopics();
|
||||
}
|
||||
|
||||
void Connection::shutdown()
|
||||
{
|
||||
if (m_topicsToRoute.empty())
|
||||
return;
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
DEBUG_LOG(m_logger) << "shutting down connection for " << m_partition
|
||||
<< ", direction: " << m_description
|
||||
<< " (" << this << "), dwt: " << m_dataWriterTask.get();
|
||||
|
||||
// inform DataWriterTask about its destruction in the near future
|
||||
// it removes it not yet sent samples and does not enqueue new samples
|
||||
if (m_dataWriterTask)
|
||||
m_dataWriterTask->shutdown();
|
||||
|
||||
// now remove topics, they don't have outstanding loans since dataWrterTask does
|
||||
// not enqueue samples anymore
|
||||
for (auto topic : m_topicsToRoute)
|
||||
{
|
||||
if (timer.elapsed() > 1000)
|
||||
{
|
||||
QCoreApplication::processEvents(); // for e.g. paceMaker
|
||||
timer.start();
|
||||
}
|
||||
topic->shutdown();
|
||||
}
|
||||
qDeleteAll(m_topicsToRoute);
|
||||
m_topicsToRoute.clear();
|
||||
|
||||
// now we can wait until the data writer task has finished
|
||||
if (m_dataWriterTask)
|
||||
{
|
||||
m_writerThread.wait();
|
||||
m_dataWriterTask = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dds::domain::DomainParticipant Connection::domainParticipant() const
|
||||
{
|
||||
return m_domainParticipant;
|
||||
}
|
||||
|
||||
dds::pub::Publisher Connection::publisher() const
|
||||
{
|
||||
return m_publisher->getDdsPublisher();
|
||||
}
|
||||
|
||||
dds::sub::Subscriber Connection::subscriber() const
|
||||
{
|
||||
return m_subscriber->getDdsSubscriber();
|
||||
}
|
||||
|
||||
bool Connection::initTopics()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Init topics for " << m_partition
|
||||
<< ", direction: " << m_description;
|
||||
|
||||
if (!m_output)
|
||||
return false;
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
auto dpOut = m_output->domainParticipant();
|
||||
auto pubOut = m_output->publisher();
|
||||
|
||||
for (auto dp : m_topicsToRoute)
|
||||
{
|
||||
if (!dp)
|
||||
continue;
|
||||
if (!dp->init(m_dataWriterTask.get(),
|
||||
m_domainParticipant,
|
||||
m_subscriber->getDdsSubscriber(),
|
||||
dpOut,
|
||||
pubOut))
|
||||
return false;
|
||||
if (timer.elapsed() > 1000)
|
||||
{
|
||||
QCoreApplication::processEvents(); // for e.g. paceMaker
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace RoutingService
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main connection handling
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <future>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class DataWriterTask;
|
||||
class TopicDispatcherInterface;
|
||||
|
||||
class Connection
|
||||
{
|
||||
public:
|
||||
Connection(const dds::domain::DomainParticipant &domainParticipant,
|
||||
const std::string &partition,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRoute,
|
||||
const std::string &desc);
|
||||
~Connection();
|
||||
|
||||
// only valid before initialize() !
|
||||
void setOutput(Connection *output);
|
||||
bool initialize();
|
||||
void shutdown();
|
||||
|
||||
dds::domain::DomainParticipant domainParticipant() const;
|
||||
dds::pub::Publisher publisher() const;
|
||||
dds::sub::Subscriber subscriber() const;
|
||||
|
||||
private:
|
||||
bool initTopics();
|
||||
|
||||
private:
|
||||
Connection *m_output;
|
||||
dds::domain::DomainParticipant m_domainParticipant;
|
||||
std::unique_ptr<DDSConnector::Publisher> m_publisher;
|
||||
std::unique_ptr<DDSConnector::Subscriber> m_subscriber;
|
||||
|
||||
std::future<void> m_writerThread;
|
||||
std::unique_ptr<DataWriterTask> m_dataWriterTask;
|
||||
|
||||
std::vector<TopicDispatcherInterface *> m_topicsToRoute;
|
||||
|
||||
std::string m_partition;
|
||||
std::string m_description;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace RoutingService
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - data writer thread
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "data_writer_task.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
DataWriterTask::DataWriterTask()
|
||||
: m_doShutdown(false)
|
||||
, m_logger(getLogger("DataWriterTask"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << this << ": init ";
|
||||
}
|
||||
|
||||
DataWriterTask::~DataWriterTask()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_queueLock);
|
||||
DEBUG_LOG(m_logger) << this << ": Cleaning up remaining writers: " << m_writerQueue.size();
|
||||
while (!m_writerQueue.empty())
|
||||
{
|
||||
delete m_writerQueue.front();
|
||||
m_writerQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void DataWriterTask::enqueue(SampleWriterInterface *swi)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_queueLock);
|
||||
TRACE_LOG(m_logger) << this << ": enqueue " << swi << " shutdown: " << m_doShutdown;
|
||||
if (m_doShutdown)
|
||||
{
|
||||
delete swi;
|
||||
return;
|
||||
}
|
||||
m_writerQueue.push(swi);
|
||||
m_waitForDataCondition.notify_one();
|
||||
}
|
||||
|
||||
void DataWriterTask::shutdown()
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_queueLock);
|
||||
m_doShutdown = true;
|
||||
DEBUG_LOG(m_logger) << this << ": Cleaning up remaining writers: " << m_writerQueue.size();
|
||||
while (!m_writerQueue.empty())
|
||||
{
|
||||
delete m_writerQueue.front();
|
||||
m_writerQueue.pop();
|
||||
}
|
||||
|
||||
m_waitForDataCondition.notify_one();
|
||||
}
|
||||
|
||||
bool DataWriterTask::waitForData()
|
||||
{
|
||||
TRACE_LOG(m_logger) << this << ": waiting for data ";
|
||||
std::unique_lock<std::mutex> waitCondLock(m_queueLock);
|
||||
while (true)
|
||||
{
|
||||
if (m_doShutdown)
|
||||
return false;
|
||||
|
||||
if (!m_writerQueue.empty())
|
||||
return true;
|
||||
|
||||
m_waitForDataCondition.wait(waitCondLock); // m_queueLock gets unlocked inside wait()
|
||||
// m_queueLock is locked now
|
||||
}
|
||||
return true; // dead code ...
|
||||
}
|
||||
|
||||
SampleWriterInterface *DataWriterTask::getNextSampleWriter()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_queueLock);
|
||||
if (m_writerQueue.empty())
|
||||
return nullptr;
|
||||
|
||||
TRACE_LOG(m_logger) << this << ": getData() queue size: " << m_writerQueue.size();
|
||||
auto ret = m_writerQueue.front();
|
||||
m_writerQueue.pop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DataWriterTask::writeSamples()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!waitForData())
|
||||
return;
|
||||
|
||||
SampleWriterInterface *swi = nullptr;
|
||||
while ((swi = getNextSampleWriter()) != nullptr)
|
||||
{
|
||||
swi->writeSamples();
|
||||
TRACE_LOG(swi->logger()) << this << ": delete " << swi;
|
||||
delete swi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RoutingService
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - data writer thread
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <DDS/Routing/routing_plugin.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class DataWriterTask final : public DataWriterTaskInterface
|
||||
{
|
||||
public:
|
||||
DataWriterTask();
|
||||
~DataWriterTask();
|
||||
|
||||
void enqueue(SampleWriterInterface *swi) override;
|
||||
void shutdown();
|
||||
bool waitForData();
|
||||
|
||||
SampleWriterInterface *getNextSampleWriter();
|
||||
void writeSamples();
|
||||
|
||||
private:
|
||||
std::queue<SampleWriterInterface *> m_writerQueue;
|
||||
std::mutex m_queueLock;
|
||||
std::condition_variable m_waitForDataCondition;
|
||||
bool m_doShutdown;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace RoutingService
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: RoutingService
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.RSC=WARN
|
||||
#log4j.logger.RSC.Connection=DEBUG
|
||||
#log4j.logger.RSC.Session=DEBUG
|
||||
#log4j.logger.RSC.PartitionHandler=DEBUG
|
||||
#log4j.logger.RSC.DataWriterTask=DEBUG
|
||||
#log4j.logger.RSC.AVM.ActiveFrequencyPlanning=DEBUG
|
||||
#log4j.logger.RSC.ASM.Asset=DEBUG
|
||||
#log4j.logger.RSC.SRP.StartReplay=TRACE
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
log4j.appender.file=Lts::RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "RSC.";
|
||||
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 RoutingService
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for ExerciseManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <RoutingServiceNG/rsccommon_export.h>
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
RSCCOMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
|
||||
} // namespace RoutingService
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* main (RoutingTest)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include "main_handler.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("RSC", "log4cxx_rsc.props");
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
constexpr int fdLimit = 100;
|
||||
struct rlimit rl;
|
||||
if (getrlimit (RLIMIT_NOFILE, &rl) == 0)
|
||||
{
|
||||
if (rl.rlim_cur < fdLimit || rl.rlim_max < fdLimit)
|
||||
{
|
||||
struct rlimit rlNew = rl;
|
||||
rlNew.rlim_cur = fdLimit;
|
||||
rlNew.rlim_max = fdLimit;
|
||||
|
||||
if (rlNew.rlim_max < rlNew.rlim_cur)
|
||||
rlNew.rlim_cur = rlNew.rlim_max;
|
||||
|
||||
if (rlNew.rlim_cur != rl.rlim_cur)
|
||||
{
|
||||
if (setrlimit (RLIMIT_NOFILE, &rlNew) == 0)
|
||||
NOTICE_LOG(app.baseLogger()) << "setting RLIMIT_NOFILE to " << rlNew.rlim_cur;
|
||||
else
|
||||
WARNING_LOG(app.baseLogger()) << "failed setting RLIMIT_NOFILE to " << fdLimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
|
||||
int ret = 0;
|
||||
{
|
||||
std::unique_ptr<RoutingService::MainHandler> handler(new RoutingService::MainHandler());
|
||||
// todo: make configurable
|
||||
if (!handler->init(options.domainId(),
|
||||
1,
|
||||
7400))
|
||||
return -2;
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
ret = app.exec();
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
|
||||
#include "main_handler.h"
|
||||
#include <LtsPluginManager/lts_plugin_loader.h>
|
||||
#include <DDS/Generic/topic_type_plugin.h>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <rti/config/Logger.hpp>
|
||||
#include <nglapplication/nglloggerhandler.h>
|
||||
|
||||
#include <Core/core_dts_types.h>
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
#include <DDS/DTS/generic_dts_impl.h>
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
MainHandler::MainHandler()
|
||||
: m_logger(getLogger("MainHandler"))
|
||||
{
|
||||
}
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
m_pacemaker = nullptr;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
bool MainHandler::init(int domainIdIn, int domainIdOut, unsigned short tcpPortOut)
|
||||
{
|
||||
shutdown();
|
||||
|
||||
if (!DDS::QosProfile::setDefault())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error setting default QoS from xml-file ";
|
||||
return false;
|
||||
}
|
||||
|
||||
NGL::LoggerHandler *lh = NGL::LoggerHandler::getLoggerHandler();
|
||||
if (lh)
|
||||
{
|
||||
const QByteArray postfix = lh->loggerNamePostfix().toLocal8Bit() + "_dds_";
|
||||
const QByteArray prefix = lh->loggerNamePrefix().toLocal8Bit();
|
||||
|
||||
rti::config::Logger &ddsLogger = rti::config::Logger::instance();
|
||||
//ddsLogger.output_file(fdopen(STDOUT_FILENO, "w"));
|
||||
ddsLogger.output_file_set(postfix.data(), prefix.data(), 10 * 1024 * 1024, 10);
|
||||
ddsLogger.verbosity(rti::config::Verbosity_def::WARNING);
|
||||
//ddsLogger.verbosity_by_category(rti::config::LogCategory_def::COMMUNICATION, rti::config::Verbosity_def::STATUS_ALL);
|
||||
}
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsConnectorIn(
|
||||
new DDSConnector::DdsConnector(domainIdIn, IDL::PartitionType::Global));
|
||||
ddsConnectorIn->initDomainParticipant();
|
||||
ddsConnectorIn->initPublisherSubscriber(); // for ExerciseManagement::Exercise, Core::SituationReplay, Heartbeat
|
||||
|
||||
QUrl tcpDiscoveryUrl;
|
||||
tcpDiscoveryUrl.setPort(tcpPortOut);
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsConnectorOut(
|
||||
new DDSConnector::DdsConnector(domainIdOut, IDL::PartitionType::Global, 0, tcpDiscoveryUrl));
|
||||
ddsConnectorOut->initDomainParticipant();
|
||||
|
||||
m_sessionHandler.reset(new SessionHandler(IDL::PartitionType::Exercise, ddsConnectorIn, ddsConnectorOut));
|
||||
|
||||
m_pacemaker = std::make_shared<Core::Pacemaker>(ddsConnectorIn);
|
||||
m_pacemaker->setNewState(Core::RunningState::Starting);
|
||||
|
||||
m_partitionHandler.reset(new PartitionHandler(ddsConnectorIn));
|
||||
connect(m_partitionHandler.get(), &PartitionHandler::createSession,
|
||||
m_sessionHandler.get(), &SessionHandler::onCreateSession);
|
||||
connect(m_partitionHandler.get(), &PartitionHandler::destroySession,
|
||||
m_sessionHandler.get(), &SessionHandler::onDestroySession);
|
||||
|
||||
if (!m_partitionHandler->init() ||
|
||||
!m_sessionHandler->init())
|
||||
{
|
||||
m_pacemaker->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString ex_0(QString::fromStdString(DDSConnector::DdsConnector::getPartitionString(IDL::PartitionType::Global)));
|
||||
m_sessionHandler->onCreateSession(ex_0, ex_0);
|
||||
|
||||
m_pacemaker->setNewState(Core::RunningState::Running);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainHandler::shutdown()
|
||||
{
|
||||
if (m_sessionHandler)
|
||||
m_sessionHandler->shutdown();
|
||||
m_sessionHandler = nullptr;
|
||||
m_partitionHandler = nullptr;
|
||||
}
|
||||
|
||||
} // namespace RoutingService
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "logger.h"
|
||||
#include "partition_handler.h"
|
||||
#include "session_handler.h"
|
||||
#include "session.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class TopicDispatcherInterface;
|
||||
|
||||
class MainHandler : public QObject
|
||||
{
|
||||
public:
|
||||
explicit MainHandler();
|
||||
~MainHandler();
|
||||
|
||||
bool init(int domainIdIn, int domainIdOut, unsigned short tcpPortOut);
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<SessionHandler> m_sessionHandler;
|
||||
std::unique_ptr<PartitionHandler> m_partitionHandler;
|
||||
std::shared_ptr<Core::Pacemaker> m_pacemaker;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace RoutingService
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - Watch for Exercises and create routes
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "partition_handler.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
PartitionHandler::PartitionHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_exmDtc(ExerciseManagement::Interface::Dtc::create(ddsConnector))
|
||||
, m_destroyTimer(new QTimer(this))
|
||||
, m_logger(getLogger("PartitionHandler"))
|
||||
{
|
||||
m_exmDtc->enableExercise();
|
||||
|
||||
m_destroyTimer->setInterval(1000);
|
||||
m_destroyTimer->setSingleShot(false);
|
||||
|
||||
connect(m_destroyTimer, &QTimer::timeout, this, &PartitionHandler::onDestroyTimerTimeout);
|
||||
}
|
||||
|
||||
PartitionHandler::~PartitionHandler()
|
||||
{
|
||||
qDeleteAll(m_destroyMap);
|
||||
}
|
||||
|
||||
bool PartitionHandler::init()
|
||||
{
|
||||
connect(m_exmDtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
|
||||
this, &PartitionHandler::onExerciseChanged);
|
||||
|
||||
m_exmDtc->exercises([this](const ExerciseManagement::Exercise &exercise) {onExerciseChanged(exercise, DataModification::eAdded);});
|
||||
return true;
|
||||
}
|
||||
|
||||
void PartitionHandler::partitionModified(const QString &partitionName, const ExerciseManagement::ExerciseState &state)
|
||||
{
|
||||
if (state == ExerciseManagement::ExerciseState::Unknown ||
|
||||
state == ExerciseManagement::ExerciseState::Terminated)
|
||||
{
|
||||
partitionRemoved(partitionName);
|
||||
return;
|
||||
}
|
||||
|
||||
m_destroyMap.remove(partitionName);
|
||||
auto it = m_activeSessions.find(partitionName);
|
||||
if (it != m_activeSessions.end())
|
||||
return;
|
||||
m_activeSessions.insert(partitionName);
|
||||
if (!m_destroyTimer->isActive())
|
||||
m_destroyTimer->start();
|
||||
|
||||
emit createSession(partitionName, partitionName);
|
||||
}
|
||||
|
||||
void PartitionHandler::partitionRemoved(const QString &partitionName)
|
||||
{
|
||||
QElapsedTimer *et = new QElapsedTimer;
|
||||
et->start();
|
||||
m_destroyMap.insert(partitionName, et);
|
||||
}
|
||||
|
||||
void PartitionHandler::onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType)
|
||||
{
|
||||
const QString partitionName(QString::fromStdString(DDSConnector::DdsConnector::getPartitionString(IDL::PartitionType::Exercise, data.id())));
|
||||
DEBUG_LOG(m_logger) << "onExerciseChanged: " << data << ", modType: " << modType;
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eRemoved:
|
||||
partitionRemoved(partitionName);
|
||||
break;
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
partitionModified(partitionName, data.state());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PartitionHandler::onDestroyTimerTimeout()
|
||||
{
|
||||
auto it = m_destroyMap.begin();
|
||||
while (it != m_destroyMap.end())
|
||||
{
|
||||
QElapsedTimer *et = it.value();
|
||||
if (et->elapsed() < 5 * 1000)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "onDestroyTimerTimeout for session " << it.key() << " triggered";
|
||||
delete et;
|
||||
m_activeSessions.remove(it.key());
|
||||
emit destroySession(it.key(), it.key());
|
||||
it = m_destroyMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace RoutingService
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - Watch for Exercises and create routes
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class PartitionHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PartitionHandler(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
||||
QObject *parent = nullptr);
|
||||
~PartitionHandler();
|
||||
|
||||
bool init();
|
||||
|
||||
private:
|
||||
void partitionModified(const QString &partitionName, const ExerciseManagement::ExerciseState &state);
|
||||
void partitionRemoved(const QString &partitionName);
|
||||
private Q_SLOTS:
|
||||
void onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType);
|
||||
void onDestroyTimerTimeout();
|
||||
Q_SIGNALS:
|
||||
void createSession(const QString &partitionNameSv, const QString &partitionNameWs);
|
||||
void destroySession(const QString &partitionNameSv, const QString &partitionNameWs);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
QMap<QString, QElapsedTimer *> m_destroyMap;
|
||||
QSet<QString> m_activeSessions;
|
||||
QTimer *m_destroyTimer;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace RoutingService
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="RoutingService" procNames="RoutingServiceNG" abbreviation="RSC" exerciseDependency="Global" groups="Core">
|
||||
<rcs>
|
||||
<Id Id="$Id$"/>
|
||||
<HeadURL HeadURL="$HeadURL$"/>
|
||||
<Author Author="$Author$"/>
|
||||
</rcs>
|
||||
<tables/>
|
||||
<dbServiceStructs/>
|
||||
<topicTypes/>
|
||||
<functionTopics/>
|
||||
<enumerations/>
|
||||
</service>
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - handle a session (connection to and from sv for a specific partition)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
|
||||
#include "session.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
Session::Session(const QString &partitionNameSv, const QString &partitionNameWs)
|
||||
: m_partitionNameSv(partitionNameSv.toStdString())
|
||||
, m_partitionNameWs(partitionNameWs.toStdString())
|
||||
, m_logger(getLogger("Session"))
|
||||
{}
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
bool Session::init(const dds::domain::DomainParticipant &dpIn,
|
||||
const dds::domain::DomainParticipant &dpOut,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRouteToWs,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRouteToSv)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Creating new session for " << m_partitionNameSv << "-" << m_partitionNameWs;
|
||||
|
||||
m_connectionSvToWs.reset(new Connection(dpIn, m_partitionNameSv, topicsToRouteToWs, "route to WS"));
|
||||
m_connectionWsToSv.reset(new Connection(dpOut, m_partitionNameWs, topicsToRouteToSv, "route from WS"));
|
||||
|
||||
m_connectionSvToWs->setOutput(m_connectionWsToSv.get());
|
||||
m_connectionWsToSv->setOutput(m_connectionSvToWs.get());
|
||||
|
||||
return m_connectionSvToWs->initialize() && m_connectionWsToSv->initialize();
|
||||
}
|
||||
|
||||
|
||||
void Session::shutdown()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Shutting down session for " << m_partitionNameSv << "-" << m_partitionNameWs;
|
||||
if (m_connectionSvToWs)
|
||||
{
|
||||
m_connectionSvToWs->shutdown();
|
||||
m_connectionSvToWs = nullptr;
|
||||
}
|
||||
if (m_connectionWsToSv)
|
||||
{
|
||||
m_connectionWsToSv->shutdown();
|
||||
m_connectionWsToSv = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace RoutingService
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - handle a session (connection to and from sv for a specific partition)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "connection.h"
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class Session
|
||||
{
|
||||
public:
|
||||
explicit Session(const QString &partitionNameSv, const QString &partitionNameWs);
|
||||
~Session();
|
||||
|
||||
bool init(const dds::domain::DomainParticipant &dpIn,
|
||||
const dds::domain::DomainParticipant &dpOut,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRouteToWs,
|
||||
const std::vector<TopicDispatcherInterface *> &topicsToRouteToSv);
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
std::string m_partitionNameSv;
|
||||
std::string m_partitionNameWs;
|
||||
std::unique_ptr<Connection> m_connectionSvToWs;
|
||||
std::unique_ptr<Connection> m_connectionWsToSv;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace RoutingService
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
|
||||
#include "session_handler.h"
|
||||
#include <LtsPluginManager/lts_plugin_loader.h>
|
||||
#include <DDS/Generic/topic_type_plugin.h>
|
||||
#include <QVector>
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
|
||||
SessionHandler::SessionHandler(IDL::PartitionType partitionType,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnectorSv,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnectorWs)
|
||||
: m_partitionType(partitionType)
|
||||
, m_ddsConnectorSv(ddsConnectorSv)
|
||||
, m_ddsConnectorWs(ddsConnectorWs)
|
||||
, m_logger(getLogger("SessionHandler"))
|
||||
{
|
||||
}
|
||||
|
||||
SessionHandler::~SessionHandler()
|
||||
{
|
||||
shutdown();
|
||||
LtsPluginManager::LtsPluginLoader::getInstance()->unloadAllPlugins();
|
||||
m_topicTypePlugins.clear();
|
||||
}
|
||||
|
||||
bool SessionHandler::init()
|
||||
{
|
||||
return loadPlugins();
|
||||
}
|
||||
|
||||
void SessionHandler::shutdown()
|
||||
{
|
||||
qDeleteAll(m_sessionMap);
|
||||
m_sessionMap.clear();
|
||||
m_ddsConnectorWs = nullptr;
|
||||
m_ddsConnectorSv = nullptr;
|
||||
}
|
||||
|
||||
void SessionHandler::onCreateSession(const QString &partitionNameSv, const QString &partitionNameWs)
|
||||
{
|
||||
const QString partitionName = partitionNameSv + QLatin1Char('-') + partitionNameWs;
|
||||
if (m_sessionMap.contains(partitionName))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Got create session for " << partitionName << ", but is already created";
|
||||
return;
|
||||
}
|
||||
Session *session = new Session(partitionNameSv, partitionNameWs);
|
||||
if (!session->init(m_ddsConnectorSv->getDomainParticipant(),
|
||||
m_ddsConnectorWs->getDomainParticipant(),
|
||||
topicsToRouteToWs(),
|
||||
topicsToRouteToSv()))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not initialize session for " << partitionName << ", routing will not work...!";
|
||||
delete session;
|
||||
return;
|
||||
}
|
||||
m_sessionMap[partitionName] = session;
|
||||
INFO_LOG(m_logger) << "Successfully created session for " << partitionName;
|
||||
}
|
||||
|
||||
void SessionHandler::onDestroySession(const QString &partitionNameSv, const QString &partitionNameWs)
|
||||
{
|
||||
const QString partitionName = partitionNameSv + QLatin1Char('-') + partitionNameWs;
|
||||
auto it = m_sessionMap.find(partitionName);
|
||||
if (it == m_sessionMap.end())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Got destroy session for " << partitionName << ", but is not created (already destroyed?)";
|
||||
return;
|
||||
}
|
||||
Session *session = it.value();
|
||||
session->shutdown();
|
||||
delete session;
|
||||
m_sessionMap.erase(it);
|
||||
INFO_LOG(m_logger) << "Successfully destroyed session for " << partitionName;
|
||||
}
|
||||
|
||||
bool SessionHandler::loadPlugins()
|
||||
{
|
||||
auto cb = [this](const LtsPluginManager::PluginInstance & pi)
|
||||
{
|
||||
return loadPlugin(pi);
|
||||
};
|
||||
return LtsPluginManager::LtsPluginLoader::getInstance()->loadPlugins(LtsPluginManager::PluginType::TOPIC_TYPE, cb);
|
||||
}
|
||||
|
||||
bool SessionHandler::loadPlugin(const LtsPluginManager::PluginInstance &pi)
|
||||
{
|
||||
DDSGeneric::TopicTypePlugin *typePlugin = dynamic_cast<DDSGeneric::TopicTypePlugin *>(pi.plugin);
|
||||
if (!typePlugin)
|
||||
return false;
|
||||
|
||||
// We don't load some plugins which are global since they are not needed since r49652ff
|
||||
static const QVector<QString> skipList({QStringLiteral("ASM"),
|
||||
QStringLiteral("AVM"),
|
||||
QStringLiteral("FLM"),
|
||||
QStringLiteral("ISM"),
|
||||
QStringLiteral("MSG"),
|
||||
QStringLiteral("OPM"),
|
||||
QStringLiteral("PDM"),
|
||||
});
|
||||
if (skipList.contains(pi.pluginName.toUpper()))
|
||||
DEBUG_LOG(m_logger) << "Skipping plugin " << pi.pluginName.toUpper() << " - is global";
|
||||
|
||||
m_topicTypePlugins.push_back(typePlugin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<TopicDispatcherInterface *> SessionHandler::topicsToRouteToWs() const
|
||||
{
|
||||
std::vector<TopicDispatcherInterface *> ret;
|
||||
for (const auto typePlugin : m_topicTypePlugins)
|
||||
{
|
||||
const auto topicsToRouteToWs = typePlugin->topicsToRouteToWs(m_partitionType);
|
||||
ret.insert(ret.end(), topicsToRouteToWs.begin(), topicsToRouteToWs.end());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<TopicDispatcherInterface *> SessionHandler::topicsToRouteToSv() const
|
||||
{
|
||||
std::vector<TopicDispatcherInterface *> ret;
|
||||
for (const auto typePlugin : m_topicTypePlugins)
|
||||
{
|
||||
const auto topicsToRouteToSv = typePlugin->topicsToRouteToSv(m_partitionType);
|
||||
ret.insert(ret.end(), topicsToRouteToSv.begin(), topicsToRouteToSv.end());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace RoutingService
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Routing Test - main object
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
#include <RoutingServiceNG/rsccommon_export.h>
|
||||
#include "logger.h"
|
||||
#include "session.h"
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
namespace LtsPluginManager
|
||||
{
|
||||
struct PluginInstance;
|
||||
}
|
||||
namespace DDSGeneric
|
||||
{
|
||||
class TopicTypePlugin;
|
||||
}
|
||||
|
||||
namespace RoutingService
|
||||
{
|
||||
class TopicDispatcherInterface;
|
||||
|
||||
class RSCCOMMON_EXPORT SessionHandler : public QObject
|
||||
{
|
||||
public:
|
||||
SessionHandler(IDL::PartitionType partitionType,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnectorSv,
|
||||
const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnectorWs);
|
||||
~SessionHandler();
|
||||
|
||||
bool init();
|
||||
void shutdown();
|
||||
|
||||
public Q_SLOTS:
|
||||
void onCreateSession(const QString &partitionNameSv, const QString &partitionNameWs);
|
||||
void onDestroySession(const QString &partitionNameSv, const QString &partitionNameWs);
|
||||
private:
|
||||
bool loadPlugins();
|
||||
bool loadPlugin(const LtsPluginManager::PluginInstance &pi);
|
||||
|
||||
std::vector<TopicDispatcherInterface *> topicsToRouteToWs() const;
|
||||
std::vector<TopicDispatcherInterface *> topicsToRouteToSv() const;
|
||||
|
||||
private:
|
||||
std::vector<DDSGeneric::TopicTypePlugin *> m_topicTypePlugins;
|
||||
|
||||
IDL::PartitionType m_partitionType;
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorSv;
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorWs;
|
||||
|
||||
QMap<QString, Session *> m_sessionMap;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace RoutingService
|
||||
Reference in new issue
Block a user