##// END OF EJS Templates
Updates AMDA provider to handle different server URLs...
Updates AMDA provider to handle different server URLs Retrieves product's attribute (if it exists) that indicates the server to use to get its data, and generates correct URL according to it

File last commit:

r943:a2f640a8dec0
r943:a2f640a8dec0
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 }