Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+324
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* 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 "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))
|
||||
, m_logger(getLogger("GroupHandler"))
|
||||
{
|
||||
}
|
||||
|
||||
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(m_logger) << "Initializing GroupHandler ...";
|
||||
|
||||
bool bAllPartsInitialized = m_heartbeatListener->init() &&
|
||||
startGroupCore(coreDomain);
|
||||
|
||||
if (bAllPartsInitialized)
|
||||
DEBUG_LOG(m_logger) << "GroupHandler successfully initialized.";
|
||||
else
|
||||
ERROR_LOG(m_logger) << "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 : qAsConst(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(m_logger) << "Could not start group Core for domain "
|
||||
<< domainId
|
||||
<< ", this ServiceManagement instance only supports domain "
|
||||
<< m_ddsHandler->connector()->getDomainId();
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "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(m_logger) << "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(m_logger) << ret();
|
||||
m_ddsHandler->fts()->startGroupReply(cookie, ret);
|
||||
}
|
||||
|
||||
void GroupHandler::slotStartGroupRequest(const GroupRequest &request)
|
||||
{
|
||||
auto ret = onStartGroup(request);
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
emit startGroupReply(ret);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject GroupHandler::onStartGroup(const GroupRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "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(m_logger) << "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(m_logger) << "Stopping all proces for domain " << domainId << ", partition " << exercisePartitionId;
|
||||
QVector<Group *> stillAliveGroups;
|
||||
|
||||
int cntStopped = 0;
|
||||
int cntAlive = 0;
|
||||
for (Group *group : qAsConst(m_groups))
|
||||
{
|
||||
if (group->exercisePartitionId() == exercisePartitionId &&
|
||||
group->domainId() == domainId)
|
||||
{
|
||||
group->stop();
|
||||
group->deleteLater();
|
||||
++cntStopped;
|
||||
}
|
||||
else
|
||||
{
|
||||
stillAliveGroups += group;
|
||||
++cntAlive;
|
||||
}
|
||||
}
|
||||
|
||||
m_groups = stillAliveGroups;
|
||||
DEBUG_LOG(m_logger) << "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(m_logger) << ret();
|
||||
m_ddsHandler->fts()->stopGroupReply(cookie, ret);
|
||||
}
|
||||
|
||||
void GroupHandler::slotStopGroupRequest(const GroupRequest &request)
|
||||
{
|
||||
auto ret = onStopGroup(request);
|
||||
if (ret.error())
|
||||
WARNING_LOG(m_logger) << ret();
|
||||
emit stopGroupReply(ret);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject GroupHandler::onStopGroup(const GroupRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "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(m_logger) << ret();
|
||||
m_ddsHandler->fts()->restartGroupReply(cookie, ret);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject GroupHandler::onRestartGroup(const GroupRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "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
|
||||
Reference in new issue
Block a user