Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/ServiceManagement/group_handler.cpp
T
torstenandCopilot b774f4035c Qt6 Migration: DDS-Stubs, Logger-Fixes, Export-Header Korrekturen
- NGL_ADD_LIBRARY2: 87 CMakeLists.txt konvertiert für Export-Header Generierung
- 44 Export-Header Include-Pfade korrigiert (_export.h)
- 81 DDS-Stub-Header generiert (*_dtc.h, *_fts.h, *_dts.h, *_ftc.h)
- INGLLogger: Duplikat gelöscht, m_logger Member entfernt, variadische Makros
- Q_FUNC_INFO Redefinition behoben (Qt6 definiert bereits)
- FATAL_LOG Makro hinzugefügt
- InfrastructureManagement DDS-Stubs (ism.hpp, ism_enums.hpp, ism_ftc.h)
- FilterManagement DDS-Stubs (flt_ftc.h, flt_dts.h)
- AreaEffectSimulation DDS-Stubs (aes.hpp, aes_enums.hpp)
- SymbolAppearance Klasse vollständig definiert mit content() Methode
- BuildingComponentFilter Klasse definiert mit Copy-Konstruktor
- Ftc Factory: nullptr Return (abstract class)
- AesFilter Klasse in aes.hpp hinzugefügt
- Dtc Klasse in ppm.hpp mit participantChanged Signal
- AesType Enum: alle 15 At* Werte definiert
- AesEffectState_def: EsReceived hinzugefügt
- DataModification Enum: eAdded/eModified/eRemoved
- function_reply_object.h → core_types.h Include-Pfad (72 Dateien)
- Enum-Class-Streaming Template-Operator in INGLLogger.h
- ism_mounting_point.h: QImage → QtGui/QImage, QGuiApplication/QScreen
- ism_data_plugin_interface.h: QSet Include, Include-Reihenfolge
- QRegExp → QRegularExpression in tpm_js_parser.cpp
- .underlying() Aufrufe zu direktem Enum-Vergleich korrigiert
- Include-Pfade: aes.hpp in symbol_appearance_settings_impl.h und aes_display_filter_impl.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 06:06:24 +02:00

325 lines
10 KiB
C++
Executable File

/**
* The GroupHandler class handles all group related classes and writes the groups state to DDS.
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-02-15
*/
#include "group_handler.h"
#include <utility>
#include "group.h"
#include "heartbeat_listener.h"
#include "service_donator.h"
namespace ServiceManagement
{
GroupHandler::GroupHandler(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<ServiceDonator> &donator)
: QObject()
, Interface::Fts::StartGroupRequestHandler(ddsHandler->fts())
, Interface::Fts::StopGroupRequestHandler(ddsHandler->fts())
, Interface::Fts::RestartGroupRequestHandler(ddsHandler->fts())
, m_serviceDonator(donator)
, m_ddsHandler(ddsHandler)
, m_heartbeatListener(new HeartbeatListener(ddsHandler->connector(), donator))
{
}
GroupHandler::~GroupHandler()
{
qDeleteAll(m_groups);
m_groups.clear();
qDeleteAll(m_groupSchemes);
m_groupSchemes.clear();
delete m_heartbeatListener;
}
bool GroupHandler::init(int32_t coreDomain)
{
DEBUG_LOG() << "Initializing GroupHandler ...";
bool bAllPartsInitialized = m_heartbeatListener->init() &&
startGroupCore(coreDomain);
if (bAllPartsInitialized)
DEBUG_LOG() << "GroupHandler successfully initialized.";
else
ERROR_LOG() << "GroupHandler initialization failed.";
return bAllPartsInitialized;
}
void GroupHandler::addServiceLink(int serviceId, Core::ServiceGroupType groupType)
{
groupSchemeFromType(groupType)->addServiceId(serviceId);
}
QVector<Group *> GroupHandler::groups() const
{
return m_groups;
}
GroupScheme *GroupHandler::groupSchemeFromType(Core::ServiceGroupType type)
{
for (GroupScheme *scheme : std::as_const(m_groupSchemes))
{
if (scheme->groupType == type)
return scheme;
}
// TODO: make generic ...
QMap<Core::ServiceGroupType, QString> groupNameMapping;
groupNameMapping.insert(Core::ServiceGroupType_def::Master, QLatin1String("Master"));
groupNameMapping.insert(Core::ServiceGroupType_def::Core, QLatin1String("Core"));
groupNameMapping.insert(Core::ServiceGroupType_def::ExercisePreparation, QLatin1String("ExercisePreparation"));
groupNameMapping.insert(Core::ServiceGroupType_def::ExerciseExecution, QLatin1String("ExerciseExecution"));
groupNameMapping.insert(Core::ServiceGroupType_def::ExercisePaused, QLatin1String("ExercisePaused"));
groupNameMapping.insert(Core::ServiceGroupType_def::ExerciseAfterActionReview, QLatin1String("ExerciseAfterActionReview"));
groupNameMapping.insert(Core::ServiceGroupType_def::Playback, QLatin1String("Playback"));
// if no scheme with type type exists, it will be newly generated and added
GroupScheme *newScheme = new GroupScheme(type, groupNameMapping.value(type));
m_groupSchemes.append(newScheme);
return newScheme;
}
Group *GroupHandler::getGroup(const GroupRequest &groupToFind) const
{
for (Group *group : m_groups)
{
if (group->type() == groupToFind.type() &&
group->exercisePartitionId() == groupToFind.exercisePartitionId() &&
group->domainId() == groupToFind.domainId() &&
group->replayPartitionId() == groupToFind.replayPartitionId())
return group;
}
return nullptr;
}
Group *GroupHandler::getSimilarGroup(const GroupRequest &groupToFind) const
{
const std::vector<Core::ServiceGroupType> possibleTypes = {Core::ServiceGroupType::ExercisePreparation,
Core::ServiceGroupType::ExerciseExecution,
Core::ServiceGroupType::ExercisePaused,
Core::ServiceGroupType::ExerciseAfterActionReview};
bool bSimilar = false;
for (const auto &type : possibleTypes)
{
if (type != groupToFind.type())
continue;
bSimilar = true;
break;
}
if (!bSimilar)
return nullptr;
for(auto type : possibleTypes)
{
// don't find ourself ...
if (type == groupToFind.type())
continue;
GroupRequest similarGroup(groupToFind);
similarGroup.type(type);
Group *groupFound = getGroup(similarGroup);
if (groupFound)
return groupFound;
}
return nullptr;
}
bool GroupHandler::startGroupCore(int32_t domainId)
{
if (domainId != m_ddsHandler->connector()->getDomainId())
{
ERROR_LOG() << "Could not start group Core for domain "
<< domainId
<< ", this ServiceManagement instance only supports domain "
<< m_ddsHandler->connector()->getDomainId();
return false;
}
DEBUG_LOG() << "Starting core group ...";
GroupRequest groupToSearch;
groupToSearch.type(Core::ServiceGroupType::Core);
groupToSearch.domainId(domainId);
Group *coreGroup = getGroup(groupToSearch);
if (coreGroup == nullptr)
{
GroupScheme *coreScheme = groupSchemeFromType(groupToSearch.type());
if (coreScheme == nullptr)
{
ERROR_LOG() << "Could not start core group because there are no services linked to it";
return false;
}
coreGroup = new Group(m_ddsHandler, m_serviceDonator, groupToSearch, coreScheme, this);
m_groups.append(coreGroup);
}
coreGroup->start();
return true;
}
void GroupHandler::onStartGroupRequest(const rti::core::SampleIdentity &cookie, const GroupRequest &request)
{
auto ret = onStartGroup(request);
if (ret.error())
WARNING_LOG() << ret();
m_ddsHandler->fts()->startGroupReply(cookie, ret);
}
void GroupHandler::slotStartGroupRequest(const GroupRequest &request)
{
auto ret = onStartGroup(request);
if (ret.error())
WARNING_LOG() << ret();
emit startGroupReply(ret);
}
Core::FunctionReplyObject GroupHandler::onStartGroup(const GroupRequest &request)
{
DEBUG_LOG() << "New StartGroupRequest: " << request;
if (request.domainId() != m_ddsHandler->connector()->getDomainId())
return Core::FunctionReplyObject(request.requestId(),
tr_lts("dds", "This instance of ServiceManagement only allows to start a group in domain %1. Domain %2 was provided"))
.arg(m_ddsHandler->connector()->getDomainId())
.arg(request.domainId());
// special case: request.type == Master, ExerciseId != 0 -> stopp all
if (request.type() == Core::ServiceGroupType::Master && request.exercisePartitionId() != 0)
return onStopAllForExercise(request.domainId(), request.exercisePartitionId());
Group *existingGroup = getGroup(request);
// check if it's a Exercise group and search a group with the same exercise/domain -id
// if the group does not exist, it is newly created (normal case)
if (existingGroup == nullptr)
{
GroupScheme *scheme = groupSchemeFromType(request.type());
if (scheme == nullptr)
return Core::FunctionReplyObject(request.requestId(),
tr_lts("dds", "Starting attempt of non existing group: %1")).arg(request.type().underlying());
existingGroup = new Group(m_ddsHandler, m_serviceDonator, request, scheme, this);
m_groups.append(existingGroup);
}
Group *similarGroup = getSimilarGroup(request);
// if there is a similar group, we should take the services from there (to avoid restarting services on exeuction -> pause or pause -> resume)
if (similarGroup)
{
DEBUG_LOG() << "Taking existing services from group " << similarGroup->type()
<< " to " << existingGroup->type();
existingGroup->takeServicesFromGroup(similarGroup);
similarGroup->stop();
m_groups.removeAll(similarGroup);
similarGroup->deleteLater();
similarGroup = nullptr;
}
existingGroup->start();
return Core::FunctionReplyObject(request.requestId());
}
Core::FunctionReplyObject GroupHandler::onStopAllForExercise(int domainId, int exercisePartitionId)
{
DEBUG_LOG() << "Stopping all proces for domain " << domainId << ", partition " << exercisePartitionId;
QVector<Group *> stillAliveGroups;
int cntStopped = 0;
int cntAlive = 0;
for (Group *group : std::as_const(m_groups))
{
if (group->exercisePartitionId() == exercisePartitionId &&
group->domainId() == domainId)
{
group->stop();
group->deleteLater();
++cntStopped;
}
else
{
stillAliveGroups += group;
++cntAlive;
}
}
m_groups = stillAliveGroups;
DEBUG_LOG() << "Stopping all proces for domain " << domainId << ", partition " << exercisePartitionId
<< " - done. Stopped " << cntStopped << " groups"
<< ", still alive: " << cntAlive;
return Core::FunctionReplyObject(exercisePartitionId);
}
void GroupHandler::onStopGroupRequest(const rti::core::SampleIdentity &cookie, const GroupRequest &request)
{
auto ret = onStopGroup(request);
if (ret.error())
WARNING_LOG() << ret();
m_ddsHandler->fts()->stopGroupReply(cookie, ret);
}
void GroupHandler::slotStopGroupRequest(const GroupRequest &request)
{
auto ret = onStopGroup(request);
if (ret.error())
WARNING_LOG() << ret();
emit stopGroupReply(ret);
}
Core::FunctionReplyObject GroupHandler::onStopGroup(const GroupRequest &request)
{
DEBUG_LOG() << "New StopGroupRequest: " << request;
Group *existingGroup = getGroup(request);
if (existingGroup == nullptr)
return Core::FunctionReplyObject(request.requestId(),
tr_lts("dds", "Could not stop Group, because it does not exist"));
existingGroup->stop();
// delete this group since no longer needed
m_groups.removeAll(existingGroup);
delete existingGroup;
return Core::FunctionReplyObject(request.requestId());
}
void GroupHandler::onRestartGroupRequest(const rti::core::SampleIdentity &cookie,
const GroupRequest &request)
{
auto ret = onRestartGroup(request);
if (ret.error())
WARNING_LOG() << ret();
m_ddsHandler->fts()->restartGroupReply(cookie, ret);
}
Core::FunctionReplyObject GroupHandler::onRestartGroup(const GroupRequest &request)
{
DEBUG_LOG() << "New RestartGroupRequest: " << request;
Group *existingGroup = getGroup(request);
if (existingGroup == nullptr)
return Core::FunctionReplyObject(tr_lts("dds", "Could not restart Group, because it does not exist"));
existingGroup->restart();
return Core::FunctionReplyObject(existingGroup->id());
}
} // namespace ServiceManagement