Files
qt5-legatus-legacy/Lts/Proxies/ComponentMonitor/component_status_handler.cpp
T
2026-08-13 18:33:10 +02:00

298 lines
9.8 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Handler for ComponentStatus
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-04-03
*/
#include "component_status_handler.h"
#include "dds_handler.h"
#include <ComponentMonitor/cmo.hpp>
#include <ComponentMonitor/cmo_dts.h>
#include <QTimer>
namespace ComponentMonitor
{
ComponentStatusHandler::ComponentStatusHandler()
: QObject()
, m_logger(getLogger("ComponentStatusHandler"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
ComponentStatusHandler::~ComponentStatusHandler()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
m_ddsHandler = nullptr;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool ComponentStatusHandler::initialize(const std::shared_ptr<DdsHandler> &ddsHandler)
{
INFO_LOG(m_logger) << LOGFUNCTION << " START initialize ComponentStatusHandler";
// initialize database
// empty / not required at CMO
// initialize DDS
m_ddsHandler = ddsHandler;
DEBUG_LOG(m_logger) << LOGFUNCTION << " ddsHandler referenced";
m_ismDtc = m_ddsHandler->ismDtc();
if (!m_ismDtc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " Failure: no ismDtc";
return false;
}
// should be enabled earlier, but be sure:
m_ismDtc->enableInstrumentationAsset();
m_ismDtc->waitForHistoricalDataInstrumentationAsset(2000);
DEBUG_LOG(m_logger) << LOGFUNCTION << " instrumentationAssets-size = " << m_ismDtc->instrumentationAssets().size();
// get all instrumentation assets and keep them up-to-date:
// InstrumentationAssetState may change (mounted, notMounted..)
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::instrumentationAssetChanged,
this, &ComponentStatusHandler::onInstrumentationAssetChanged);
// get:
m_ismDtc->instrumentationAssets([this](const InfrastructureManagement::InstrumentationAsset & iAsset)
{
onInstrumentationAssetChanged(iAsset, DataModification::eAdded);
});
// with a delay, dump state of each entry
QTimer::singleShot(35000, this, &ComponentStatusHandler::dump);
DEBUG_LOG(m_logger) << LOGFUNCTION << "initialize succesful, statusMapSize=" << statusMapSize();
INFO_LOG(m_logger) << LOGFUNCTION << " END initialize ComponentStatusHandler, statusMapSize=" << statusMapSize();
return true;
}
std::vector<std::string> ComponentStatusHandler::getHostnames() const
{
std::vector<std::string> ret;
ret.reserve(m_statusMap.size());
for (CONST_ITERATOR_T it = m_statusMap.cbegin(); it != m_statusMap.cend(); ++it)
ret.push_back(it->hostname());
return ret;
}
void ComponentStatusHandler::onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &iAsset,
DataModification dataMod)
{
const InfrastructureManagement::MountingPointType_def::type mpType = iAsset.mountingPointTypeId().underlying();
if ((mpType != InfrastructureManagement::MountingPointType_def::IndoorCamera) &&
(mpType != InfrastructureManagement::MountingPointType_def::OutdoorCamera) &&
(mpType != InfrastructureManagement::MountingPointType_def::EffectGenerationControlUnit) &&
(mpType != InfrastructureManagement::MountingPointType_def::BuildingSensorModule)
)
return; // [GUEZE-1489]: just IndoorCamera, OutdoorCamera, EGCU, BSM
static int assetChangedCounter = 0;
const int iAssetId = iAsset.id();
DEBUG_LOG(m_logger) << LOGFUNCTION
<< ", iAssetId=" << iAssetId
<< " (assetChangedCounter=" << ++assetChangedCounter << ")";
// Only mounted assets should be monitored:
const bool bIsMounted = iAsset.assetStateId() == InfrastructureManagement::InstrumentationAssetState_def::Mounted;
if (!bIsMounted)
dataMod = DataModification::eRemoved;
// hostname ist empty?
const bool bNoHostname = iAsset.hostname().empty();
if (bNoHostname)
dataMod = DataModification::eRemoved;
ITERATOR_T it = m_statusMap.find(iAssetId);
switch (dataMod)
{
case DataModification::eAdded:
case DataModification::eModified:
{
ComponentStatus cs;
cs.id(iAssetId);
cs.hostname(iAsset.hostname());
cs.state(ComponentMonitor::ComponentState::Undefined);
addUpdateInstrumentationAsset(it, cs);
}
break;
case DataModification::eRemoved:
{
// remove only, if in internal map
if (it != m_statusMap.end())
removeInstrumentationAsset(it);
}
break;
default:
// empty
break;
}
}
void ComponentStatusHandler::dump()
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << LOGFUNCTION << " DUMP START";
int counter = 0;
// 1) write all Reachable:
counter = 0;
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << " REACHABLE:";
for (const ComponentStatus &status : qAsConst(m_statusMap))
{
if (status.state().underlying() == ComponentState_def::Reachable)
{
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Reachable";
++counter;
}
} // for
DEBUG_LOG(m_logger) << " REACHABLE hostCounter = " << counter;
// 2) write all UnReachable:
counter = 0;
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << " UNREACHABLE:";
for (const ComponentStatus &status : qAsConst(m_statusMap))
{
if (status.state().underlying() == ComponentState_def::Unreachable)
{
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Unreachable";
++counter;
}
} // for
DEBUG_LOG(m_logger) << " UNREACHABLE hostCounter = " << counter;
// 3) write all Undefined:
counter = 0;
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << " UNDEFINED:";
for (const ComponentStatus &status : qAsConst(m_statusMap))
{
if (status.state().underlying() == ComponentState_def::Undefined)
{
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Undefined";
++counter;
}
} // for
DEBUG_LOG(m_logger) << " UNDEFINED hostCounter = " << counter;
DEBUG_LOG(m_logger) << LOGFUNCTION << " DUMP END";
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
}
void ComponentStatusHandler::onNewState(const QString &hostname, bool reachable, long long lastCheckSec)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " hostname=" << hostname
<< ", reachable=" << reachable
<< ", lastCheckSec=" << lastCheckSec;
if (hostname.isEmpty())
return;
for (ITERATOR_T it = m_statusMap.begin(); it != m_statusMap.end(); ++it)
{
const QString hname = QString::fromStdString(it->hostname());
if (hname.compare(hostname, Qt::CaseInsensitive) == 0)
{
ComponentState_def::type newStateInner = reachable ? ComponentState_def::Reachable : ComponentState_def::Unreachable;
ComponentStatus newCs = (*it);
newCs.state(newStateInner);
newCs.last_check(lastCheckSec);
addUpdateInstrumentationAsset(it, newCs);
}
} // for
}
void ComponentStatusHandler::onUpdateLastCheckTimeDirect(const QStringList &hostnamesForUpdateLastCheckTime, qint64 lastCheckSec)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START hostnamesForLastCheckTime=" << hostnamesForUpdateLastCheckTime.join(QStringLiteral(";"));
for (ITERATOR_T it = m_statusMap.begin(); it != m_statusMap.end(); ++it)
{
ComponentStatus &cs = *it;
const QString &curHostname = QString::fromStdString(cs.hostname());
if (!hostnamesForUpdateLastCheckTime.contains(curHostname, Qt::CaseInsensitive))
continue;
// do not step backwards:
if (lastCheckSec <= cs.last_check())
continue;
const ComponentState_def::type curState = cs.state().underlying();
if ((curState == ComponentState_def::Reachable) ||
(curState == ComponentState_def::Unreachable))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " updateLastCheckTimeDirect"
<< " host: '" << curHostname << "'"
<< " newLastCheck= " << lastCheckSec;
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF_2a (*it) " << (*it);
cs.last_check(lastCheckSec);
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF_2b (*it) " << (*it);
m_ddsHandler->dts()->publish(cs);
}
} // for
}
bool ComponentStatusHandler::addUpdateInstrumentationAsset(ComponentStatusHandler::ITERATOR_T it,
const ComponentStatus &cs)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " START add/Update: cs=" << cs
<< ", curSize=" << m_statusMap.size() << ")";
const int id = cs.id();
if (it != m_statusMap.end())
{
// real update?
// (avoid publishing the same data)
if ((*it) != cs)
{
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF (*it) " << (*it);
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF cs " << cs;
(*it) = cs; // m_statusMap.insert(id, cs);
m_ddsHandler->dts()->publish(cs);
}
}
else
{
// insert and publish:
m_statusMap.insert(id, cs);
m_ddsHandler->dts()->publish(cs);
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " END add/Update: cs=" << cs
<< ", curSize=" << m_statusMap.size() << ")";
return true;
}
bool ComponentStatusHandler::removeInstrumentationAsset(ComponentStatusHandler::ITERATOR_T it)
{
const int id = it.value().id();
DEBUG_LOG(m_logger) << LOGFUNCTION << " remove: id=" << id;
m_statusMap.remove(id);
m_ddsHandler->dts()->removeComponentStatusByKey(id);
return true;
}
} // namespace ComponentMonitor