Files
2026-08-13 18:33:10 +02:00

203 lines
7.2 KiB
C++
Executable File

/**
* MainHandler for ServiceManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 15.02.2016
*/
#include "main_handler.h"
#include "licence_handler.h"
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QDirIterator>
#include <QtCore/QFile>
#include <QtCore/QXmlStreamReader>
#include <ngltools/ngltools_filesystem.h>
#include <nglapplication/nglsinglecoreapplication.h>
#include <CodeGen/XmlReader.h>
#include "service.h"
namespace ServiceManagement
{
MainHandler::MainHandler(QObject *parent)
: QObject(parent)
, m_ddsHandler(nullptr)
, m_groupHandler(nullptr)
, m_licenceHandler(nullptr)
, m_serviceHandler(nullptr)
, m_websocketHandler(nullptr)
, m_logger(getLogger("MainHandler"))
{
QtSingleCoreApplication *sa = qobject_cast<QtSingleCoreApplication*>(QCoreApplication::instance());
Q_ASSERT(sa);
connect(sa, &QtSingleCoreApplication::messageReceived,
this, &MainHandler::onMessageFromCommandlineReceived);
}
MainHandler::~MainHandler()
{
m_websocketHandler = nullptr;
m_groupHandler = nullptr;
m_serviceHandler = nullptr;
m_licenceHandler = nullptr;
m_ddsHandler = nullptr;
}
bool MainHandler::init(int domainId, const QString &licenceFile)
{
DEBUG_LOG(m_logger) << "Initializing MainHandler ...";
m_ddsHandler = std::make_shared<DdsHandler>(domainId);
bool bAllPartsInitialized = m_ddsHandler->init();
ERROR_LOG(m_logger) << "Searching for licence file: " << licenceFile;
QString licenceFileName = NGL::findFile(NGL::FileType::ConfigFile, licenceFile);
m_licenceHandler = std::make_shared<LicenceHandler>(m_ddsHandler, licenceFileName);
if (!m_licenceHandler->init())
{
ERROR_LOG(m_logger) << "Initialisation LicenceHandler failed.";
return false;
}
m_serviceHandler = std::make_shared<ServiceHandler>(m_ddsHandler, m_licenceHandler);
m_groupHandler = std::make_shared<GroupHandler>(m_ddsHandler, m_serviceHandler);
bAllPartsInitialized &=
m_serviceHandler->init() &&
readServices() &&
m_groupHandler->init(domainId);
if (bAllPartsInitialized)
{
// WebSocketServer
m_websocketHandler = std::make_shared<WebSocketInterface::WebSocketInterfaceHandler>(this);
if (!m_websocketHandler->init())
{
ERROR_LOG(m_logger) << "Initialisation WebSocketInterfaceHandler failed.";
return false;
}
DEBUG_LOG(m_logger) << "MainHandler successfully initialized :)";
}
else
{
ERROR_LOG(m_logger) << "MainHandler initialization failed";
}
return bAllPartsInitialized;
}
std::shared_ptr<GroupHandler> MainHandler::groupHandler() const
{
return m_groupHandler;
}
bool MainHandler::readServices()
{
CodeGen::XmlReader xmlReader;
const QString xmlPath = NGL::directory(NGL::FileType::ConfigFile, QLatin1String("xml"));
DEBUG_LOG(m_logger) << "Using xml path " << xmlPath;
QDirIterator directoryIterator(xmlPath);
int serviceCount = 0;
// TODO: make generic ... will be implemented in a future core library
QMap<QString, Core::ServiceGroupType_def::type> groupNameMapping;
groupNameMapping.insert(QLatin1String("Master"), Core::ServiceGroupType_def::Master);
groupNameMapping.insert(QLatin1String("Core"), Core::ServiceGroupType_def::Core);
groupNameMapping.insert(QLatin1String("ExercisePreparation"), Core::ServiceGroupType_def::ExercisePreparation);
groupNameMapping.insert(QLatin1String("ExerciseExecution"), Core::ServiceGroupType_def::ExerciseExecution);
groupNameMapping.insert(QLatin1String("ExercisePaused"), Core::ServiceGroupType_def::ExercisePaused);
groupNameMapping.insert(QLatin1String("ExerciseAfterActionReview"), Core::ServiceGroupType_def::ExerciseAfterActionReview);
groupNameMapping.insert(QLatin1String("Playback"), Core::ServiceGroupType_def::Playback);
while (directoryIterator.hasNext())
{
QString currentFileName = directoryIterator.next();
if (currentFileName.endsWith(QLatin1String(".xml")))
{
if (xmlReader.readServiceFile(currentFileName, QString()))
{
const auto procNames = xmlReader.getProcNames();
for (const QString &serviceName : procNames)
{
const QString exeName = QLatin1String("svc") + serviceName;
const QStringList groupNames = xmlReader.getGroupNames();
if (serviceName.isEmpty() || exeName.length() < 4 || groupNames.isEmpty())
{
INFO_LOG(m_logger) << currentFileName
<< " does not include complete service information.";
}
else
{
if (m_licenceHandler->isServiceLicensed(serviceName))
{
const QString serviceNameShort = xmlReader.getServiceAbbr();
QString fnNoRestart = xmlPath + serviceNameShort + QLatin1String(".dontRestart");
bool bDevMode = xmlReader.getDevMode() || QFile::exists(fnNoRestart);
const int prioService = xmlReader.getPrio();
if (bDevMode)
{
WARNING_LOG(m_logger) << "Developer mode for service " << serviceName
<< " activated - no automatic restart on crash!";
}
Service *newService = new Service(serviceName,
exeName,
QCoreApplication::applicationDirPath(),
serviceNameShort,
groupNames,
bDevMode,
prioService);
m_serviceHandler->addService(newService);
DEBUG_LOG(m_logger) << "Added new service \""
<< serviceName
<< "\""
<< " prio=" << prioService;
for (const QString &groupName : groupNames)
{
if (groupNameMapping.contains(groupName))
{
DEBUG_LOG(m_logger) << " --> Linking to group \""
<< groupName
<< "\"";
if (serviceName == QStringLiteral("ReportAnalyzer") && (groupName == QStringLiteral("ExercisePaused") || groupName == QStringLiteral("ExerciseAfterActionReview")))
// Do not start ReportAnalyzer for stopped exercises
continue;
m_groupHandler->addServiceLink(newService->id(), groupNameMapping.value(groupName));
}
else
INFO_LOG(m_logger) << "Found unknown group name: " << groupName;
}
++ serviceCount;
}
else
NOTICE_LOG(m_logger) << "Service " << serviceName << " is not licensed.";
}
}
}
}
}
if (serviceCount)
return true;
ERROR_LOG(m_logger) << "Could not find any valid service in directory " << xmlPath;
return false;
}
void MainHandler::onMessageFromCommandlineReceived()
{
NOTICE_LOG(m_logger) << "Got shutdown message from command line - trying to properly shut down all running applications";
QCoreApplication::quit();
}
} // namespace ServiceManagement