298 lines
9.8 KiB
C++
Executable File
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
|