Browse Source

ComponentInformationManager: use file cache

QGC4.4
Beat Küng 4 years ago committed by Don Gagne
parent
commit
33cc58efdc
  1. 173
      src/Vehicle/ComponentInformationManager.cc
  2. 21
      src/Vehicle/ComponentInformationManager.h

173
src/Vehicle/ComponentInformationManager.cc

@ -46,6 +46,7 @@ int RequestMetaDataTypeStateMachine::_cStates = sizeof(RequestMetaDataTypeStateM
ComponentInformationManager::ComponentInformationManager(Vehicle* vehicle) ComponentInformationManager::ComponentInformationManager(Vehicle* vehicle)
: _vehicle (vehicle) : _vehicle (vehicle)
, _requestTypeStateMachine (this) , _requestTypeStateMachine (this)
, _fileCache(ComponentInformationCache::defaultInstance())
{ {
_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_GENERAL] = new CompInfoGeneral (MAV_COMP_ID_AUTOPILOT1, vehicle, this); _compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_GENERAL] = new CompInfoGeneral (MAV_COMP_ID_AUTOPILOT1, vehicle, this);
_compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_PARAMETER] = new CompInfoParam (MAV_COMP_ID_AUTOPILOT1, vehicle, this); _compInfoMap[MAV_COMP_ID_AUTOPILOT1][COMP_METADATA_TYPE_PARAMETER] = new CompInfoParam (MAV_COMP_ID_AUTOPILOT1, vehicle, this);
@ -133,6 +134,12 @@ CompInfoGeneral* ComponentInformationManager::compInfoGeneral(uint8_t compId)
return _compInfoMap.contains(compId) && _compInfoMap[compId].contains(COMP_METADATA_TYPE_GENERAL) ? qobject_cast<CompInfoGeneral*>(_compInfoMap[compId][COMP_METADATA_TYPE_GENERAL]) : nullptr; return _compInfoMap.contains(compId) && _compInfoMap[compId].contains(COMP_METADATA_TYPE_GENERAL) ? qobject_cast<CompInfoGeneral*>(_compInfoMap[compId][COMP_METADATA_TYPE_GENERAL]) : nullptr;
} }
QString ComponentInformationManager::_getFileCacheTag(int compInfoType, uint32_t crc, bool isTranslation)
{
return QString::asprintf("%08x_%02i_%i", crc, compInfoType, (int)isTranslation);
}
RequestMetaDataTypeStateMachine::RequestMetaDataTypeStateMachine(ComponentInformationManager* compMgr) RequestMetaDataTypeStateMachine::RequestMetaDataTypeStateMachine(ComponentInformationManager* compMgr)
: _compMgr(compMgr) : _compMgr(compMgr)
{ {
@ -229,152 +236,125 @@ void RequestMetaDataTypeStateMachine::_stateRequestCompInfo(StateMachine* stateM
} }
} }
QString RequestMetaDataTypeStateMachine::_downloadCompleteJsonWorker(const QString& fileName, const QString& inflatedFileName) QString RequestMetaDataTypeStateMachine::_downloadCompleteJsonWorker(const QString& fileName)
{ {
QString outputFileName = fileName; QString outputFileName = fileName;
if (fileName.endsWith(".lzma", Qt::CaseInsensitive) || fileName.endsWith(".xz", Qt::CaseInsensitive)) { if (fileName.endsWith(".lzma", Qt::CaseInsensitive) || fileName.endsWith(".xz", Qt::CaseInsensitive)) {
outputFileName = (QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).absoluteFilePath(inflatedFileName)); outputFileName = (QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).absoluteFilePath(_currentCacheFileTag));
if (QGCLZMA::inflateLZMAFile(fileName, outputFileName)) { if (QGCLZMA::inflateLZMAFile(fileName, outputFileName)) {
QFile(fileName).remove(); QFile(fileName).remove();
} else { } else {
qCWarning(ComponentInformationManagerLog) << "Inflate of compressed json failed" << inflatedFileName; qCWarning(ComponentInformationManagerLog) << "Inflate of compressed json failed" << _currentCacheFileTag;
outputFileName.clear(); outputFileName.clear();
} }
} else { } else {
outputFileName = fileName; outputFileName = fileName;
} }
if (_currentFileValidCrc) {
// cache the file (this will move/remove the temp file as well)
outputFileName = _compMgr->fileCache().insert(_currentCacheFileTag, outputFileName);
}
return outputFileName; return outputFileName;
} }
void RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson(const QString& fileName, const QString& errorMsg) void RequestMetaDataTypeStateMachine::_ftpDownloadComplete(const QString& fileName, const QString& errorMsg)
{ {
qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson fileName:errorMsg" << fileName << errorMsg; qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadComplete fileName:errorMsg" << fileName << errorMsg;
disconnect(_compInfo->vehicle->ftpManager(), &FTPManager::downloadComplete, this, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson); disconnect(_compInfo->vehicle->ftpManager(), &FTPManager::downloadComplete, this, &RequestMetaDataTypeStateMachine::_ftpDownloadComplete);
if (errorMsg.isEmpty()) { if (errorMsg.isEmpty()) {
_jsonMetadataFileName = _downloadCompleteJsonWorker(fileName, "metadata.json"); if (_currentFileName) {
*_currentFileName = _downloadCompleteJsonWorker(fileName);
}
} else if (qgcApp()->runningUnitTests()) { } else if (qgcApp()->runningUnitTests()) {
// Unit test should always succeed // Unit test should always succeed
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson failed filename:errorMsg" << fileName << errorMsg; qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadComplete failed filename:errorMsg" << fileName << errorMsg;
} } // TODO: else: try fallback uri
advance(); advance();
} }
void RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson(const QString& fileName, const QString& errorMsg) void RequestMetaDataTypeStateMachine::_httpDownloadComplete(QString remoteFile, QString localFile, QString errorMsg)
{ {
QString jsonTranslationFileName; qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadComplete remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg;
qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson fileName:errorMsg" << fileName << errorMsg; disconnect(qobject_cast<QGCFileDownload*>(sender()), &QGCFileDownload::downloadComplete, this, &RequestMetaDataTypeStateMachine::_httpDownloadComplete);
disconnect(_compInfo->vehicle->ftpManager(), &FTPManager::downloadComplete, this, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson);
if (errorMsg.isEmpty()) { if (errorMsg.isEmpty()) {
_jsonTranslationFileName = _downloadCompleteJsonWorker(fileName, "translation.json"); if (_currentFileName) {
*_currentFileName = _downloadCompleteJsonWorker(localFile);
}
} else if (qgcApp()->runningUnitTests()) { } else if (qgcApp()->runningUnitTests()) {
// Unit test should always succeed // Unit test should always succeed
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson failed filename:errorMsg" << fileName << errorMsg; qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson failed remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg;
} } // TODO: else: try fallback uri
advance(); advance();
} }
void RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson(QString remoteFile, QString localFile, QString errorMsg) void RequestMetaDataTypeStateMachine::_requestFile(const QString& cacheFileTag, bool crcValid, const QString& uri, QString& outputFileName)
{ {
qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg; FTPManager* ftpManager = _compInfo->vehicle->ftpManager();
_currentCacheFileTag = cacheFileTag;
disconnect(qobject_cast<QGCFileDownload*>(sender()), &QGCFileDownload::downloadComplete, this, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson); _currentFileName = &outputFileName;
if (errorMsg.isEmpty()) { _currentFileValidCrc = crcValid;
_jsonMetadataFileName = _downloadCompleteJsonWorker(localFile, "metadata.json");
} else if (qgcApp()->runningUnitTests()) { if (_compInfo->available() && !uri.isEmpty()) {
// Unit test should always succeed const QString cachedFile = crcValid ? _compMgr->fileCache().access(cacheFileTag) : "";
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson failed remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg;
if (cachedFile.isEmpty()) {
qCDebug(ComponentInformationManagerLog) << "Downloading json" << uri;
if (_uriIsMAVLinkFTP(uri)) {
connect(ftpManager, &FTPManager::downloadComplete, this, &RequestMetaDataTypeStateMachine::_ftpDownloadComplete);
if (!ftpManager->download(uri, QStandardPaths::writableLocation(QStandardPaths::TempLocation))) {
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_requestFile FTPManager::download returned failure";
disconnect(ftpManager, &FTPManager::downloadComplete, this, &RequestMetaDataTypeStateMachine::_ftpDownloadComplete);
// TODO: try fallback uri
advance();
} }
} else {
QGCFileDownload* download = new QGCFileDownload(this);
connect(download, &QGCFileDownload::downloadComplete, this, &RequestMetaDataTypeStateMachine::_httpDownloadComplete);
if (!download->download(uri)) {
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_requestFile QGCFileDownload::download returned failure";
disconnect(download, &QGCFileDownload::downloadComplete, this, &RequestMetaDataTypeStateMachine::_httpDownloadComplete);
// TODO: try fallback uri
advance(); advance();
} }
void RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson(QString remoteFile, QString localFile, QString errorMsg)
{
QString jsonTranslationFileName;
qCDebug(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg;
disconnect(qobject_cast<QGCFileDownload*>(sender()), &QGCFileDownload::downloadComplete, this, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson);
if (errorMsg.isEmpty()) {
_jsonTranslationFileName = _downloadCompleteJsonWorker(localFile, "translation.json");
} else if (qgcApp()->runningUnitTests()) {
// Unit test should always succeed
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson failed remoteFile:localFile:errorMsg" << remoteFile << localFile << errorMsg;
} }
} else {
qCDebug(ComponentInformationManagerLog) << "Using cached file" << cachedFile;
outputFileName = cachedFile;
advance();
}
} else {
qCDebug(ComponentInformationManagerLog) << "Skipping download. Component information not available for" << _currentCacheFileTag;
advance(); advance();
} }
}
void RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson(StateMachine* stateMachine) void RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson(StateMachine* stateMachine)
{ {
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine); RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine);
CompInfo* compInfo = requestMachine->compInfo(); CompInfo* compInfo = requestMachine->compInfo();
FTPManager* ftpManager = compInfo->vehicle->ftpManager(); const QString fileTag = ComponentInformationManager::_getFileCacheTag(
compInfo->type, compInfo->crcMetaData(), false);
if (compInfo->available()) { const QString uri = compInfo->uriMetaData();
qCDebug(ComponentInformationManagerLog) << "Downloading metadata json" << compInfo->uriMetaData(); requestMachine->_jsonMetadataCrcValid = compInfo->crcMetaDataValid();
if (_uriIsMAVLinkFTP(compInfo->uriMetaData())) { requestMachine->_requestFile(fileTag, compInfo->crcMetaDataValid(), uri, requestMachine->_jsonMetadataFileName);
connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson);
if (!ftpManager->download(compInfo->uriMetaData(), QStandardPaths::writableLocation(QStandardPaths::TempLocation))) {
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson FTPManager::download returned failure";
disconnect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteMetaDataJson);
requestMachine->advance();
}
} else {
QGCFileDownload* download = new QGCFileDownload(requestMachine);
connect(download, &QGCFileDownload::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson);
if (!download->download(compInfo->uriMetaData())) {
qCWarning(ComponentInformationManagerLog) << "RequestMetaDataTypeStateMachine::_stateRequestMetaDataJson QGCFileDownload::download returned failure";
disconnect(download, &QGCFileDownload::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteMetaDataJson);
requestMachine->advance();
}
}
} else {
qCDebug(ComponentInformationManagerLog) << "Skipping metadata json download. Component information not available";
requestMachine->advance();
}
} }
void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine* stateMachine) void RequestMetaDataTypeStateMachine::_stateRequestTranslationJson(StateMachine* stateMachine)
{ {
RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine); RequestMetaDataTypeStateMachine* requestMachine = static_cast<RequestMetaDataTypeStateMachine*>(stateMachine);
CompInfo* compInfo = requestMachine->compInfo(); CompInfo* compInfo = requestMachine->compInfo();
FTPManager* ftpManager = compInfo->vehicle->ftpManager(); const QString fileTag = ComponentInformationManager::_getFileCacheTag(
compInfo->type, compInfo->crcTranslation(), true);
if (compInfo->available()) { const QString uri = compInfo->uriTranslation();
if (compInfo->uriTranslation().isEmpty()) { requestMachine->_jsonTranslationCrcValid = compInfo->crcTranslationValid();
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. No translation json specified"; requestMachine->_requestFile(fileTag, compInfo->crcTranslationValid(), uri, requestMachine->_jsonTranslationFileName);
requestMachine->advance();
} else {
qCDebug(ComponentInformationManagerLog) << "Downloading translation json" << compInfo->uriTranslation();
if (_uriIsMAVLinkFTP(compInfo->uriTranslation())) {
connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson);
if (!ftpManager->download(compInfo->uriTranslation(), QStandardPaths::writableLocation(QStandardPaths::TempLocation))) {
qCWarning(ComponentInformationManagerLog) << "_stateRequestTranslationJson::_stateRequestMetaDataJson FTPManager::download returned failure";
connect(ftpManager, &FTPManager::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_ftpDownloadCompleteTranslationJson);
requestMachine->advance();
}
} else {
QGCFileDownload* download = new QGCFileDownload(requestMachine);
connect(download, &QGCFileDownload::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson);
if (!download->download(compInfo->uriTranslation())) {
qCWarning(ComponentInformationManagerLog) << "_stateRequestTranslationJson::_stateRequestMetaDataJson QGCFileDownload::download returned failure";
disconnect(download, &QGCFileDownload::downloadComplete, requestMachine, &RequestMetaDataTypeStateMachine::_httpDownloadCompleteTranslationJson);
requestMachine->advance();
}
}
}
} else {
qCDebug(ComponentInformationManagerLog) << "Skipping translation json download. Component information not available";
requestMachine->advance();
}
} }
void RequestMetaDataTypeStateMachine::_stateRequestComplete(StateMachine* stateMachine) void RequestMetaDataTypeStateMachine::_stateRequestComplete(StateMachine* stateMachine)
@ -384,10 +364,11 @@ void RequestMetaDataTypeStateMachine::_stateRequestComplete(StateMachine* stateM
compInfo->setJson(requestMachine->_jsonMetadataFileName, requestMachine->_jsonTranslationFileName); compInfo->setJson(requestMachine->_jsonMetadataFileName, requestMachine->_jsonTranslationFileName);
if (!requestMachine->_jsonMetadataFileName.isEmpty()) { // if we don't have a CRC we didn't cache the file and we need to delete it
if (!requestMachine->_jsonMetadataCrcValid && !requestMachine->_jsonMetadataFileName.isEmpty()) {
QFile(requestMachine->_jsonMetadataFileName).remove(); QFile(requestMachine->_jsonMetadataFileName).remove();
} }
if (!requestMachine->_jsonTranslationFileName.isEmpty()) { if (!requestMachine->_jsonMetadataCrcValid && !requestMachine->_jsonTranslationFileName.isEmpty()) {
QFile(requestMachine->_jsonTranslationFileName).remove(); QFile(requestMachine->_jsonTranslationFileName).remove();
} }

21
src/Vehicle/ComponentInformationManager.h

@ -12,6 +12,7 @@
#include "QGCLoggingCategory.h" #include "QGCLoggingCategory.h"
#include "QGCMAVLink.h" #include "QGCMAVLink.h"
#include "StateMachine.h" #include "StateMachine.h"
#include "ComponentInformationCache.h"
Q_DECLARE_LOGGING_CATEGORY(ComponentInformationManagerLog) Q_DECLARE_LOGGING_CATEGORY(ComponentInformationManagerLog)
@ -38,11 +39,9 @@ public:
void statesCompleted (void) const final; void statesCompleted (void) const final;
private slots: private slots:
void _ftpDownloadCompleteMetaDataJson (const QString& file, const QString& errorMsg); void _ftpDownloadComplete (const QString& file, const QString& errorMsg);
void _ftpDownloadCompleteTranslationJson (const QString& file, const QString& errorMsg); void _httpDownloadComplete (QString remoteFile, QString localFile, QString errorMsg);
void _httpDownloadCompleteMetaDataJson (QString remoteFile, QString localFile, QString errorMsg); QString _downloadCompleteJsonWorker (const QString& jsonFileName);
void _httpDownloadCompleteTranslationJson(QString remoteFile, QString localFile, QString errorMsg);
QString _downloadCompleteJsonWorker (const QString& jsonFileName, const QString& inflatedFileName);
private: private:
static void _stateRequestCompInfo (StateMachine* stateMachine); static void _stateRequestCompInfo (StateMachine* stateMachine);
@ -51,11 +50,18 @@ private:
static void _stateRequestComplete (StateMachine* stateMachine); static void _stateRequestComplete (StateMachine* stateMachine);
static bool _uriIsMAVLinkFTP (const QString& uri); static bool _uriIsMAVLinkFTP (const QString& uri);
void _requestFile(const QString& cacheFileTag, bool crcValid, const QString& uri, QString& outputFileName);
ComponentInformationManager* _compMgr = nullptr; ComponentInformationManager* _compMgr = nullptr;
CompInfo* _compInfo = nullptr; CompInfo* _compInfo = nullptr;
QString _jsonMetadataFileName; QString _jsonMetadataFileName;
bool _jsonMetadataCrcValid = false;
QString _jsonTranslationFileName; QString _jsonTranslationFileName;
bool _jsonTranslationCrcValid = false;
QString* _currentFileName = nullptr;
QString _currentCacheFileTag;
bool _currentFileValidCrc = false;
static StateFn _rgStates[]; static StateFn _rgStates[];
static int _cStates; static int _cStates;
@ -79,11 +85,15 @@ public:
int stateCount (void) const final; int stateCount (void) const final;
const StateFn* rgStates (void) const final; const StateFn* rgStates (void) const final;
ComponentInformationCache& fileCache() { return _fileCache; }
private: private:
void _stateRequestCompInfoComplete (void); void _stateRequestCompInfoComplete (void);
bool _isCompTypeSupported (COMP_METADATA_TYPE type); bool _isCompTypeSupported (COMP_METADATA_TYPE type);
void _updateAllUri (); void _updateAllUri ();
static QString _getFileCacheTag(int compInfoType, uint32_t crc, bool isTranslation);
static void _stateRequestCompInfoGeneral (StateMachine* stateMachine); static void _stateRequestCompInfoGeneral (StateMachine* stateMachine);
static void _stateRequestCompInfoGeneralComplete(StateMachine* stateMachine); static void _stateRequestCompInfoGeneralComplete(StateMachine* stateMachine);
static void _stateRequestCompInfoParam (StateMachine* stateMachine); static void _stateRequestCompInfoParam (StateMachine* stateMachine);
@ -93,6 +103,7 @@ private:
RequestMetaDataTypeStateMachine _requestTypeStateMachine; RequestMetaDataTypeStateMachine _requestTypeStateMachine;
RequestAllCompleteFn _requestAllCompleteFn = nullptr; RequestAllCompleteFn _requestAllCompleteFn = nullptr;
void* _requestAllCompleteFnData = nullptr; void* _requestAllCompleteFnData = nullptr;
ComponentInformationCache& _fileCache;
QMap<uint8_t /* compId */, QMap<COMP_METADATA_TYPE, CompInfo*>> _compInfoMap; QMap<uint8_t /* compId */, QMap<COMP_METADATA_TYPE, CompInfo*>> _compInfoMap;

Loading…
Cancel
Save