/** * @RDE_HEADER@ * ImportHandler * $Id$ * $HeadURL$ * $Author$ * Created by Astrid Müller, Christian Fröbel, SLSE, 2017-12-12 */ #include "import_handler.h" #include "exercise_handler.h" #include #include #include #include #include using namespace AudioVideoManagement; namespace { Database::AvmDeviceConfig toDb(const ExerciseContext &context, const AssetManagement::Asset &asset) { Database::AvmDeviceConfig deviceConfig; deviceConfig.context = context.toString(); deviceConfig.type = QStringLiteral("IMPORT_VIDEO_CHANNEL"); deviceConfig.name = QStringLiteral("ECRS"); deviceConfig.controller = QString::fromStdString(asset.name()); deviceConfig.definition = QStringLiteral("recording=ECRS@EXCAVS01"); return deviceConfig; } } // anonymous namespace namespace AudioVideoManagement { ImportHandler *ImportHandler::create(ExerciseHandler *exerciseHandler, DatabaseInterface *db, AssetManagement::Interface::Dtc *asmDtc) { Q_ASSERT(exerciseHandler); ImportHandler *newHandler = new ImportHandler(exerciseHandler->context(), db, asmDtc); connect(exerciseHandler, &ExerciseHandler::contextActivated, newHandler, &ImportHandler::onContextActivated); connect(exerciseHandler, &ExerciseHandler::contextDeactivated, newHandler, &ImportHandler::onContextDeactivated); connect(asmDtc, &AssetManagement::Interface::Dtc::assetChanged, newHandler, &ImportHandler::onAssetChanged); return newHandler; } ImportHandler::ImportHandler(const ExerciseContext &context, DatabaseInterface *db, AssetManagement::Interface::Dtc *asmDtc) : m_context(context) , m_db(db) , m_asmDtc(asmDtc) { Q_ASSERT(db); Q_ASSERT(asmDtc); } void ImportHandler::onContextActivated() { m_isActive = true; DBTransaction transaction(m_db->database()); // This can possibly cause a race condition. It can happen that for an asset we just retrieved // we immediatly get an onAssetChanged() notification with eAdded. auto cb = [this] (const AssetManagement::Asset &asset) { onAssetChanged(asset, DataModification::eAdded); }; m_asmDtc->assets(cb); transaction.commit(); } void ImportHandler::onContextDeactivated() { DBTransaction transaction(m_db->database()); for (const auto &idAndDeviceConfig: m_deviceConfigs) m_db->removeAvmDeviceConfig(idAndDeviceConfig.second.id); m_deviceConfigs.clear(); transaction.commit(); m_isActive = false; } void ImportHandler::onAssetChanged(const AssetManagement::Asset &asset, DataModification modType) { if (!m_isActive) return; if (asset.assetTypeId() != AssetManagement::AssetType::Workstation) return; // Guard against a possible race condition, see comments in onContextActivated(). auto found = m_deviceConfigs.find(asset.id()); if (found != m_deviceConfigs.end()) return; switch (modType) { case DataModification::eAdded: addToDb(asset); break; case DataModification::eRemoved: // This is not a regular use case. // But it can happen when the services are stopped. removeFromDb(asset); break; case DataModification::eModified: // Assets are read-only. Q_ASSERT(false); } } void ImportHandler::addToDb(const AssetManagement::Asset &asset) { Database::AvmDeviceConfig newConfig = ::toDb(m_context, asset); m_db->insert(newConfig); auto insertResult = m_deviceConfigs.insert({asset.id(), newConfig}); Q_ASSERT(insertResult.second); emit avDbReloadNeeded(); } void ImportHandler::removeFromDb(const AssetManagement::Asset &asset) { auto found = m_deviceConfigs.find(asset.id()); Q_ASSERT(found != m_deviceConfigs.end()); m_db->removeAvmDeviceConfig(found->second.id); m_deviceConfigs.erase(found); emit avDbReloadNeeded(); } } // namespace AudioVideoManagement