##// END OF EJS Templates
Parser refactoring (5)...
Parser refactoring (5) Replaces the basic parser to use the helpers created

File last commit:

r943:a2f640a8dec0
r948:64a6137ab3a2
Show More
AmdaProvider.cpp
304 lines | 11.6 KiB | text/x-c | CppLexer
Alexandre Leroux
Inits Amda provider
r377 #include "AmdaProvider.h"
Alexandre Leroux
Amda provider update (2)...
r413 #include "AmdaDefs.h"
Alexandre Leroux
Amda provider (3)...
r380 #include "AmdaResultParser.h"
Alexandre Leroux
Uses DateUtils
r488 #include <Common/DateUtils.h>
Alexandre Leroux
Amda provider (1)...
r378 #include <Data/DataProviderParameters.h>
Modify the AmdaProvider to remove from it all network controller...
r388 #include <Network/NetworkController.h>
#include <SqpApplication.h>
#include <Variable/Variable.h>
Alexandre Leroux
Amda provider (1)...
r378
#include <QNetworkAccessManager>
#include <QNetworkReply>
Alexandre Leroux
Amda provider (2)...
r379 #include <QTemporaryFile>
Modify the AmdaProvider to remove from it all network controller...
r388 #include <QThread>
Alexandre Leroux
Inits Amda provider
r377
Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
Alexandre Leroux
Amda provider (1)...
r378 namespace {
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 /// URL of the default AMDA server
const auto AMDA_SERVER_URL = QStringLiteral("amda.irap.omp.eu");
/// URL of the AMDA test server
const auto AMDA_TEST_SERVER_URL = QStringLiteral("amdatest.irap.omp.eu");
Alexandre Leroux
Amda provider (1)...
r378 /// URL format for a request on AMDA server. The parameters are as follows:
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 /// - %1: server URL
/// - %2: start date
/// - %3: end date
/// - %4: parameter id
Alexandre Leroux
Changes url
r790 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
Alexandre Leroux
Amda provider (1)...
r378 const auto AMDA_URL_FORMAT = QStringLiteral(
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 "http://%1/php/rest/"
"getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
Alexandre Leroux
Amda provider (1)...
r378 "timeFormat=ISO8601&gzip=0");
/// Dates format passed in the URL (e.g 2013-09-23T09:00)
Log AMDA get url of the file and the download file
r440 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
Alexandre Leroux
Amda provider (1)...
r378
/// Formats a time to a date that can be passed in URL
Change SqpRange for SqpDateTime
r512 QString dateFormat(double sqpRange) noexcept
Alexandre Leroux
Amda provider (1)...
r378 {
Change SqpRange for SqpDateTime
r512 auto dateTime = DateUtils::dateTime(sqpRange);
Alexandre Leroux
Amda provider (1)...
r378 return dateTime.toString(AMDA_TIME_FORMAT);
}
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 /// Returns the URL of the AMDA server queried for requests, depending on the type of server passed
/// as a parameter
QString serverURL(const QString &server)
{
if (server == QString{"amdatest"}) {
return AMDA_TEST_SERVER_URL;
}
else {
return AMDA_SERVER_URL;
}
}
Alexandre Leroux
Reads variable metadata to get the data type...
r566 AmdaResultParser::ValueType valueType(const QString &valueType)
{
if (valueType == QStringLiteral("scalar")) {
return AmdaResultParser::ValueType::SCALAR;
}
else if (valueType == QStringLiteral("vector")) {
return AmdaResultParser::ValueType::VECTOR;
}
else {
return AmdaResultParser::ValueType::UNKNOWN;
}
}
Alexandre Leroux
Amda provider (1)...
r378 } // namespace
Alexandre Leroux
Amda provider cleaning...
r409 AmdaProvider::AmdaProvider()
Alexandre Leroux
Inits Amda provider
r377 {
Alexandre Leroux
Minor refactoring...
r460 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
Modify the AmdaProvider to remove from it all network controller...
r388 if (auto app = sqpApp) {
auto &networkController = app->networkController();
Implement progression for AmdaProvider.
r752 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
Alexandre Leroux
Updates signal to be valid on Windows
r416 std::function<void(QNetworkReply *, QUuid)>)),
&networkController,
Implement progression for AmdaProvider.
r752 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
Alexandre Leroux
Updates signal to be valid on Windows
r416 std::function<void(QNetworkReply *, QUuid)>)));
Remove connection for progress from NC -> VC to NC -> Provider.
r425
Implementation of progression
r750 connect(&sqpApp->networkController(),
Implement progression for AmdaProvider.
r752 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
this,
SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
Modify the AmdaProvider to remove from it all network controller...
r388 }
Alexandre Leroux
Inits Amda provider
r377 }
Alexandre Leroux
Generates and registers clone provider
r712 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
{
// No copy is made in the clone
return std::make_shared<AmdaProvider>();
}
Implementation of V5 acquisition
r539 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
Alexandre Leroux
Inits Amda provider
r377 {
// NOTE: Try to use multithread if possible
Alexandre Leroux
Updates IDataProvider::requestDataLoading() method's signature...
r408 const auto times = parameters.m_Times;
Alexandre Leroux
Amda provider update (2)...
r413 const auto data = parameters.m_Data;
Alexandre Leroux
Updates IDataProvider::requestDataLoading() method's signature...
r408 for (const auto &dateTime : qAsConst(times)) {
Implementation of automatic cancel for request that failed
r761 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
<< dateTime;
Add synchronization part of v5 acquisition
r540 this->retrieveData(acqIdentifier, dateTime, data);
Correction for MR
r546
Implementation of progression
r750
Add sleep to permits AMDA to wait 1 sec between each request
r628 // TORM when AMDA will support quick asynchrone request
QThread::msleep(1000);
Alexandre Leroux
Inits Amda provider
r377 }
}
Implementation of V5 acquisition
r539 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
Implement of the abort download process
r422 {
if (auto app = sqpApp) {
auto &networkController = app->networkController();
Implementation of V5 acquisition
r539 networkController.onReplyCanceled(acqIdentifier);
Implement of the abort download process
r422 }
}
Implementation of progression
r750 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
Implement progression for AmdaProvider.
r752 std::shared_ptr<QNetworkRequest> networkRequest,
double progress)
Implementation of progression
r750 {
Correction for MR
r760 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
<< networkRequest.get() << progress;
Implementation of progression
r750 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
Correction for MR
r760 // Update the progression for the current request
Implement progression for AmdaProvider.
r752 auto requestPtr = networkRequest;
auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
Implementation of progression
r750
auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
auto requestProgressMapEnd = requestProgressMap.end();
auto requestProgressMapIt
= std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
if (requestProgressMapIt != requestProgressMapEnd) {
requestProgressMapIt->second = progress;
}
else {
Fix progression bug when aborting a request for Amda plugin
r758 // This case can happened when a progression is send after the request has been
// finished.
// Generaly the case when aborting a request
Implementation of automatic cancel for request that failed
r761 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
<< networkRequest.get() << progress;
Implementation of progression
r750 }
Correction for MR
r760 // Compute the current final progress and notify it
Implementation of progression
r750 double finalProgress = 0.0;
auto fraq = requestProgressMap.size();
for (auto requestProgress : requestProgressMap) {
finalProgress += requestProgress.second;
Correction for MR
r760 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
Implement progression for AmdaProvider.
r752 << finalProgress << requestProgress.second;
Implementation of progression
r750 }
if (fraq > 0) {
finalProgress = finalProgress / fraq;
}
Correction for MR
r760 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
Implementation of progression
r750 emit dataProvidedProgress(acqIdentifier, finalProgress);
}
else {
Fix progression bug when aborting a request for Amda plugin
r758 // This case can happened when a progression is send after the request has been finished.
// Generaly the case when aborting a request
emit dataProvidedProgress(acqIdentifier, 100.0);
Implementation of progression
r750 }
}
Change SqpRange for SqpDateTime
r512 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
Alexandre Leroux
Amda provider (1)...
r378 {
Alexandre Leroux
Amda provider update (2)...
r413 // Retrieves product ID from data: if the value is invalid, no request is made
auto productId = data.value(AMDA_XML_ID_KEY).toString();
if (productId.isNull()) {
qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
return;
}
Alexandre Leroux
Reads variable metadata to get the data type...
r566 // Retrieves the data type that determines whether the expected format for the result file is
// scalar, vector...
auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 // Gets the server being queried to retrieve the product. It's then used to set the server URL
auto productServer = data.value(AMDA_SERVER_KEY).toString();
Alexandre Leroux
Amda provider (1)...
r378 // /////////// //
// Creates URL //
// /////////// //
Alexandre Leroux
Updates IDataProvider::requestDataLoading() method's signature...
r408 auto startDate = dateFormat(dateTime.m_TStart);
auto endDate = dateFormat(dateTime.m_TEnd);
Alexandre Leroux
Amda provider (1)...
r378
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 auto url = QUrl{
QString{AMDA_URL_FORMAT}.arg(serverURL(productServer), startDate, endDate, productId)};
Correction for MR
r760 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
Modify the AmdaProvider to remove from it all network controller...
r388 auto tempFile = std::make_shared<QTemporaryFile>();
Alexandre Leroux
Amda provider (1)...
r378
Modify the AmdaProvider to remove from it all network controller...
r388 // LAMBDA
Alexandre Leroux
Reads variable metadata to get the data type...
r566 auto httpDownloadFinished = [this, dateTime, tempFile,
productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
// Don't do anything if the reply was abort
Correction for MR
r760 if (reply->error() == QNetworkReply::NoError) {
Alexandre Leroux
Reads variable metadata to get the data type...
r566
if (tempFile) {
auto replyReadAll = reply->readAll();
if (!replyReadAll.isEmpty()) {
tempFile->write(replyReadAll);
}
tempFile->close();
// Parse results file
if (auto dataSeries
= AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
emit dataProvided(dataId, dataSeries, dateTime);
}
else {
/// @todo ALX : debug
Implementation of automatic cancel for request that failed
r761 emit dataProvidedFailed(dataId);
Alexandre Leroux
Reads variable metadata to get the data type...
r566 }
}
Implementation of progression
r750 m_AcqIdToRequestProgressMap.erase(dataId);
Alexandre Leroux
Reads variable metadata to get the data type...
r566 }
Correction for MR
r760 else {
qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
Implementation of automatic cancel for request that failed
r761 emit dataProvidedFailed(dataId);
Correction for MR
r760 }
Alexandre Leroux
Reads variable metadata to get the data type...
r566
};
Add implementation of abort impact on Amda plugin
r431 auto httpFinishedLambda
= [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
Alexandre Leroux
Amda provider (2)...
r379
Add implementation of abort impact on Amda plugin
r431 // Don't do anything if the reply was abort
Correction for MR
r760 if (reply->error() == QNetworkReply::NoError) {
Alexandre Leroux
Updates AMDA provider to handle different server URLs...
r943 auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
Implement of the abort download process
r422
Correction for MR
r760 qCInfo(LOG_AmdaProvider())
Correction for MR
r546 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
Add implementation of abort impact on Amda plugin
r431 // Executes request for downloading file //
Modify the AmdaProvider to remove from it all network controller...
r388
Add implementation of abort impact on Amda plugin
r431 // Creates destination file
if (tempFile->open()) {
Implement progression for AmdaProvider.
r752 // Executes request and store the request for progression
Implementation of progression
r750 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
updateRequestProgress(dataId, request, 0.0);
Implement progression for AmdaProvider.
r752 emit requestConstructed(request, dataId, httpDownloadFinished);
Add implementation of abort impact on Amda plugin
r431 }
Implementation of automatic cancel for request that failed
r761 else {
emit dataProvidedFailed(dataId);
}
Add implementation of abort impact on Amda plugin
r431 }
Implementation of progression
r750 else {
Correction for MR
r760 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
Implementation of progression
r750 m_AcqIdToRequestProgressMap.erase(dataId);
Implementation of automatic cancel for request that failed
r761 emit dataProvidedFailed(dataId);
Implementation of progression
r750 }
Add implementation of abort impact on Amda plugin
r431 };
Modify the AmdaProvider to remove from it all network controller...
r388
// //////////////// //
// Executes request //
// //////////////// //
Implementation of progression
r750
auto request = std::make_shared<QNetworkRequest>(url);
Implement progression for AmdaProvider.
r752 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
Implementation of progression
r750 updateRequestProgress(token, request, 0.0);
Implement progression for AmdaProvider.
r752 emit requestConstructed(request, token, httpFinishedLambda);
Implementation of progression
r750 }
void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
std::shared_ptr<QNetworkRequest> request, double progress)
{
Run request canceling when unit isn"t found in the file. Clean log.
r828 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress request") << request.get();
Implementation of progression
r750 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
auto requestProgressMapIt = requestProgressMap.find(request);
if (requestProgressMapIt != requestProgressMap.end()) {
requestProgressMapIt->second = progress;
Implement progression for AmdaProvider.
r752 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
<< acqIdentifier << request.get() << progress;
Implementation of progression
r750 }
else {
Implement progression for AmdaProvider.
r752 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
<< request.get() << progress;
Implementation of progression
r750 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
}
}
else {
Implement progression for AmdaProvider.
r752 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
<< acqIdentifier << request.get() << progress;
Implementation of progression
r750 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
requestProgressMap.insert(std::make_pair(request, progress));
m_AcqIdToRequestProgressMap.insert(
std::make_pair(acqIdentifier, std::move(requestProgressMap)));
}
Alexandre Leroux
Inits Amda provider
r377 }