Files
qt5-legatus-legacy/Lts/Plugins/ServiceManagement/Gui/ServiceEdit/scm_dialog.cpp
T
2026-08-13 18:33:10 +02:00

366 lines
11 KiB
C++
Executable File

/**
* @RDE_HEADER@
* HMI Plugin for ExerciseManangement - Exercise Overview Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2016-03-30
*/
#include "scm_dialog.h"
#include "ui_scm_dialog.h"
#include "scm_dialog_group.h"
#include "scm_dialog_service.h"
#include <LtsUtilsCore/data_modification_enum.h>
#include <QVBoxLayout>
namespace ServiceManagement
{
//---------------------------------
// ServiceManagementDialog
//---------------------------------
ServiceManagementDialog::ServiceManagementDialog(QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ui(new Ui::ServiceManagementDialog)
, m_dtcExm(nullptr)
, m_dtc(nullptr)
, m_ftc(nullptr)
, m_logger(getLogger("ServiceManagementDialog"))
{
m_ui->setupUi(this);
// unused yet
m_ui->lbGroupsIndicator->hide();
m_ui->lbExercise->hide();
m_ui->lbServer->hide();
m_ui->cbServer->hide();
m_ui->cbExercise->hide();
setOnlineHelpFilename(QStringLiteral("Administrator-Service_Management"));
}
ServiceManagementDialog::~ServiceManagementDialog()
{
delete m_ui;
}
void ServiceManagementDialog::retranslate()
{
translate(m_ui, tr("Service Management"));
}
bool ServiceManagementDialog::init(const std::shared_ptr<ServiceManagement::Interface::Dtc> &dtc,
const std::shared_ptr<ServiceManagement::Interface::Ftc> &ftc,
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &dtcExm)
{
m_dtc = dtc;
m_ftc = ftc;
m_dtcExm = dtcExm;
connect(m_dtc.get(), &Interface::Dtc::groupInformationChanged,
this, &ServiceManagementDialog::slotGroupInformationChanged);
connect(m_dtc.get(), &Interface::Dtc::serviceInformationChanged,
this, &ServiceManagementDialog::slotServiceInformationChanged);
const QMap<qint32, ServiceManagement::GroupInformation> groupInfo = m_dtc->groupInformations();
if (groupInfo.isEmpty())
{
INFO_LOG(m_logger) << "initModel - no groups!";
return true;
}
m_ui->lbNoServices->hide();
INFO_LOG(m_logger) << "initModel - #group information: " << groupInfo.size();
// GROUPS
QVector<int> servicesList;
for (const ServiceManagement::GroupInformation &gi : groupInfo)
{
// now that all services of that group are represented by a widget, create the group widget which adds all service widgets
//const int id = gi.id();
const int server = gi.domainId();
const int exercise = gi.exercisePartitionId();
const int32_t replayPartitionId = gi.replayPartitionId();
const QString groupName = groupEnumToGroupName(gi.type()); // QLatin1String("Group Name"); // TODO: get real group name
long long timestamp = gi.timestamp();
servicesList.clear();
servicesList.reserve(gi.services().size());
for (auto service : gi.services())
servicesList.append(service);
addGroup(gi.type(), server, exercise, replayPartitionId, groupName, timestamp, servicesList);
}
// SERVICES
auto cbSvc = [this](const ServiceManagement::ServiceInformation & svc) // create widgets for every service in the group
{
addService(svc);
};
m_dtc->serviceInformations(cbSvc); // needed to resolve services for the groups
return true;
}
GroupWidget *ServiceManagementDialog::addGroup(const Core::ServiceGroupType &groupType, int server, int exercise, int32_t replayPartitionId,
const QString &groupName, long long timestamp, const QVector<int> &servicesList)
{
//qWarning() << "ServiceManagementDialog::addGroup: needed services:" << servicesList;
QString exName = QString::fromStdString(m_dtcExm.get()->exercise(exercise).name());
GroupWidget *group = new GroupWidget(groupType, server, exercise, replayPartitionId, exName, timestamp, servicesList); // memleak!
QString groupObjectName = craftGroupName(server, exercise, groupName);
group->setObjectName(groupObjectName);
//qWarning() << "Group Object Name =" << groupObjectName;
connect(group, &GroupWidget::signalRestartGroup, this, &ServiceManagementDialog::slotRestartGroup); // direct connection for const ref on group type enum
connect(group, &GroupWidget::signalStartGroup, this, &ServiceManagementDialog::slotStartGroup); // direct connection for const ref on group type enum
connect(group, &GroupWidget::signalStopGroup, this, &ServiceManagementDialog::slotStopGroup); // direct connection for const ref on group type enum
QVBoxLayout *l = qobject_cast<QVBoxLayout *>(m_ui->groupLayoutWidget->layout());
if (!l)
WARNING_LOG(m_logger) << "ServiceManagementDialog::addGroup: group layout failed, cannot add group";
else
l->addWidget(group, 0, Qt::AlignTop);
return group;
}
void ServiceManagementDialog::slotRestartService(int serviceID)
{
const RestartServiceRequest req(serviceID);
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->restartServiceRequest(req, this);
});
}
static int s_requestId = 0;
void ServiceManagementDialog::slotRestartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
{
const GroupRequest req(groupType,
exercise,
server,
replayPartitionId,
++s_requestId,
{});
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->restartGroupRequest(req, this);
});
}
void ServiceManagementDialog::slotStartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
{
const GroupRequest req(groupType,
exercise,
server,
replayPartitionId,
++s_requestId,
{});
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->startGroupRequest(req, this);
});
}
void ServiceManagementDialog::slotStopGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
{
const GroupRequest req(groupType,
exercise,
server,
replayPartitionId,
++s_requestId,
{});
m_requestHelper->startSingleRequest([req, this]()
{
return m_ftc->stopGroupRequest(req, this);
});
}
// DTC Modifications
void ServiceManagementDialog::slotGroupInformationChanged(ServiceManagement::GroupInformation info, DataModification mod)
{
//qWarning() << "slotGroupInformationChanged";
// find group
int server = info.domainId();
int exercise = info.exercisePartitionId();
int32_t replayPartitionId = info.replayPartitionId();
QString groupName = groupEnumToGroupName(info.type());
long long timestamp = info.timestamp();
QString findGroupName = craftGroupName(server, exercise, groupName);
GroupWidget *gw = m_ui->groupLayoutWidget->findChild<GroupWidget *>(findGroupName);
if (!gw) // group does not exist? create it!
{
//qWarning() << "slotGroupInformationChanged: group not found, adding it";
QVector<int> servicesList;
servicesList.reserve(info.services().size());
for (auto service : info.services())
servicesList << service;
m_ui->lbNoServices->hide();
addGroup(info.type(), server, exercise, replayPartitionId, groupName, timestamp, servicesList);
}
else
{
switch (mod)
{
case DataModification::eAdded: // already exists, so it cant be added - but easily change data in existing group
case DataModification::eModified:
{
//qWarning() << "slotGroupInformationChanged: group added or modified";
m_ui->lbNoServices->hide(); // added/modified = there are groups, which show services
gw->setType(info.type());
gw->setServer(server);
gw->setExercise(exercise);
gw->setTimestamp(timestamp);
break;
}
case DataModification::eRemoved:
{
//qWarning() << "slotGroupInformationChanged: group removed";
if (m_ui->groupLayoutWidget->findChildren<GroupWidget *>().isEmpty()) // no groups to show services in?
m_ui->lbNoServices->show();
delete gw; // then delete gw from layout
break;
}
}
}
}
void ServiceManagementDialog::addService(const ServiceManagement::ServiceInformation &svc)
{
const int id = svc.id();
const long long pid = svc.pid();
const QString name(QString::fromStdString(svc.name()));
const Core::RunningState &state = svc.state();
const QString errorString(QString::fromStdString(svc.errorString()));
ServiceWidget *service = new ServiceWidget(id, pid, name, state, errorString);
service->setObjectName(QLatin1String("service.") + QString::number(id));
connect(service, &ServiceWidget::signalRestartService, this, &ServiceManagementDialog::slotRestartService);
const auto groupList = findChildren<GroupWidget *>();
for (GroupWidget *gw : groupList)
gw->addService(service);
}
void ServiceManagementDialog::slotServiceInformationChanged(ServiceManagement::ServiceInformation info, DataModification mod)
{
//qWarning() << "slotServiceInformationChanged";
// find services (because ONE service can be in MANY groups)
int32_t serviceId = info.id();
QString errorString = QString::fromStdString(info.errorString());
QString serviceName = QString::fromStdString(info.name());
long long pid = info.pid();
const Core::RunningState &state = info.state();
long long timestamp = info.timestamp();
QString findServiceName = QLatin1String("service.") + QString::number(serviceId);
const auto serviceList = findChildren<ServiceWidget *>(findServiceName);
if (serviceList.isEmpty() || mod == DataModification::eAdded) // no service found or is going to be added? add it!
{
//qWarning() << "slotServiceInformationChanged: service not found, adding it";
addService(info);
}
for (ServiceWidget *serviceWidget : serviceList)
{
switch (mod)
{
case DataModification::eModified:
{
//qWarning() << "slotServiceInformationChanged: service modified";
serviceWidget->setErrorString(errorString);
serviceWidget->setName(serviceName);
serviceWidget->setPid(pid);
serviceWidget->setState(state);
serviceWidget->setTimestamp(timestamp);
break;
}
case DataModification::eRemoved:
{
//qWarning() << "slotServiceInformationChanged: service removed";
delete serviceWidget;
serviceWidget = nullptr;
break;
}
default:
{
//qWarning() << "ServiceManagementDialog::slotServiceInformationChanged: unknown or invalid modification!";
break;
}
}
}
// tell all groups to set their new statuses (bcuz service states may have changed) !!
const auto groupList = findChildren<GroupWidget *>();
for (GroupWidget *groupWidget : groupList)
groupWidget->checkStatus();
}
} // namespace ServiceManagement