##// END OF EJS Templates
Uses previous class to set url when retrieving data
Alexandre Leroux -
r1148:bf7a208fcc65
parent child
Show More
@@ -1,307 +1,287
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4 #include "AmdaServer.h"
4
5
5 #include <Common/DateUtils.h>
6 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
8 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
9 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
10 #include <Variable/Variable.h>
10
11
11 #include <QNetworkAccessManager>
12 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
13 #include <QNetworkReply>
13 #include <QTemporaryFile>
14 #include <QTemporaryFile>
14 #include <QThread>
15 #include <QThread>
15
16
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
18
18 namespace {
19 namespace {
19
20
20 /// URL of the default AMDA server
21 const auto AMDA_SERVER_URL = QStringLiteral("amda.irap.omp.eu");
22
23 /// URL of the AMDA test server
24 const auto AMDA_TEST_SERVER_URL = QStringLiteral("amdatest.irap.omp.eu");
25
26 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// URL format for a request on AMDA server. The parameters are as follows:
27 /// - %1: server URL
22 /// - %1: server URL
28 /// - %2: start date
23 /// - %2: start date
29 /// - %3: end date
24 /// - %3: end date
30 /// - %4: parameter id
25 /// - %4: parameter id
31 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
26 /// AMDA V2: http://amdatest.irap.omp.eu/php/rest/
32 const auto AMDA_URL_FORMAT = QStringLiteral(
27 const auto AMDA_URL_FORMAT = QStringLiteral(
33 "http://%1/php/rest/"
28 "http://%1/php/rest/"
34 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
29 "getParameter.php?startTime=%2&stopTime=%3&parameterID=%4&outputFormat=ASCII&"
35 "timeFormat=ISO8601&gzip=0");
30 "timeFormat=ISO8601&gzip=0");
36
31
37 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
32 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
38 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
33 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
39
34
40 /// Formats a time to a date that can be passed in URL
35 /// Formats a time to a date that can be passed in URL
41 QString dateFormat(double sqpRange) noexcept
36 QString dateFormat(double sqpRange) noexcept
42 {
37 {
43 auto dateTime = DateUtils::dateTime(sqpRange);
38 auto dateTime = DateUtils::dateTime(sqpRange);
44 return dateTime.toString(AMDA_TIME_FORMAT);
39 return dateTime.toString(AMDA_TIME_FORMAT);
45 }
40 }
46
41
47 /// Returns the URL of the AMDA server queried for requests, depending on the type of server passed
48 /// as a parameter
49 QString serverURL(const QString &server)
50 {
51 if (server == QString{"amdatest"}) {
52 return AMDA_TEST_SERVER_URL;
53 }
54 else {
55 return AMDA_SERVER_URL;
56 }
57 }
58
59 AmdaResultParser::ValueType valueType(const QString &valueType)
42 AmdaResultParser::ValueType valueType(const QString &valueType)
60 {
43 {
61 if (valueType == QStringLiteral("scalar")) {
44 if (valueType == QStringLiteral("scalar")) {
62 return AmdaResultParser::ValueType::SCALAR;
45 return AmdaResultParser::ValueType::SCALAR;
63 }
46 }
64 else if (valueType == QStringLiteral("spectrogram")) {
47 else if (valueType == QStringLiteral("spectrogram")) {
65 return AmdaResultParser::ValueType::SPECTROGRAM;
48 return AmdaResultParser::ValueType::SPECTROGRAM;
66 }
49 }
67 else if (valueType == QStringLiteral("vector")) {
50 else if (valueType == QStringLiteral("vector")) {
68 return AmdaResultParser::ValueType::VECTOR;
51 return AmdaResultParser::ValueType::VECTOR;
69 }
52 }
70 else {
53 else {
71 return AmdaResultParser::ValueType::UNKNOWN;
54 return AmdaResultParser::ValueType::UNKNOWN;
72 }
55 }
73 }
56 }
74
57
75 } // namespace
58 } // namespace
76
59
77 AmdaProvider::AmdaProvider()
60 AmdaProvider::AmdaProvider()
78 {
61 {
79 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
62 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
80 if (auto app = sqpApp) {
63 if (auto app = sqpApp) {
81 auto &networkController = app->networkController();
64 auto &networkController = app->networkController();
82 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
65 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
83 std::function<void(QNetworkReply *, QUuid)>)),
66 std::function<void(QNetworkReply *, QUuid)>)),
84 &networkController,
67 &networkController,
85 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
68 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
86 std::function<void(QNetworkReply *, QUuid)>)));
69 std::function<void(QNetworkReply *, QUuid)>)));
87
70
88
71
89 connect(&sqpApp->networkController(),
72 connect(&sqpApp->networkController(),
90 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
73 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
91 this,
74 this,
92 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
75 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
93 }
76 }
94 }
77 }
95
78
96 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
79 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
97 {
80 {
98 // No copy is made in the clone
81 // No copy is made in the clone
99 return std::make_shared<AmdaProvider>();
82 return std::make_shared<AmdaProvider>();
100 }
83 }
101
84
102 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
85 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
103 {
86 {
104 // NOTE: Try to use multithread if possible
87 // NOTE: Try to use multithread if possible
105 const auto times = parameters.m_Times;
88 const auto times = parameters.m_Times;
106 const auto data = parameters.m_Data;
89 const auto data = parameters.m_Data;
107 for (const auto &dateTime : qAsConst(times)) {
90 for (const auto &dateTime : qAsConst(times)) {
108 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
91 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
109 << dateTime;
92 << dateTime;
110 this->retrieveData(acqIdentifier, dateTime, data);
93 this->retrieveData(acqIdentifier, dateTime, data);
111
94
112
95
113 // TORM when AMDA will support quick asynchrone request
96 // TORM when AMDA will support quick asynchrone request
114 QThread::msleep(1000);
97 QThread::msleep(1000);
115 }
98 }
116 }
99 }
117
100
118 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
101 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
119 {
102 {
120 if (auto app = sqpApp) {
103 if (auto app = sqpApp) {
121 auto &networkController = app->networkController();
104 auto &networkController = app->networkController();
122 networkController.onReplyCanceled(acqIdentifier);
105 networkController.onReplyCanceled(acqIdentifier);
123 }
106 }
124 }
107 }
125
108
126 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
109 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
127 std::shared_ptr<QNetworkRequest> networkRequest,
110 std::shared_ptr<QNetworkRequest> networkRequest,
128 double progress)
111 double progress)
129 {
112 {
130 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
113 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
131 << networkRequest.get() << progress;
114 << networkRequest.get() << progress;
132 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
115 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
133 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
116 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
134
117
135 // Update the progression for the current request
118 // Update the progression for the current request
136 auto requestPtr = networkRequest;
119 auto requestPtr = networkRequest;
137 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
120 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
138
121
139 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
122 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
140 auto requestProgressMapEnd = requestProgressMap.end();
123 auto requestProgressMapEnd = requestProgressMap.end();
141 auto requestProgressMapIt
124 auto requestProgressMapIt
142 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
125 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
143
126
144 if (requestProgressMapIt != requestProgressMapEnd) {
127 if (requestProgressMapIt != requestProgressMapEnd) {
145 requestProgressMapIt->second = progress;
128 requestProgressMapIt->second = progress;
146 }
129 }
147 else {
130 else {
148 // This case can happened when a progression is send after the request has been
131 // This case can happened when a progression is send after the request has been
149 // finished.
132 // finished.
150 // Generaly the case when aborting a request
133 // Generaly the case when aborting a request
151 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
134 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
152 << networkRequest.get() << progress;
135 << networkRequest.get() << progress;
153 }
136 }
154
137
155 // Compute the current final progress and notify it
138 // Compute the current final progress and notify it
156 double finalProgress = 0.0;
139 double finalProgress = 0.0;
157
140
158 auto fraq = requestProgressMap.size();
141 auto fraq = requestProgressMap.size();
159
142
160 for (auto requestProgress : requestProgressMap) {
143 for (auto requestProgress : requestProgressMap) {
161 finalProgress += requestProgress.second;
144 finalProgress += requestProgress.second;
162 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
145 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
163 << finalProgress << requestProgress.second;
146 << finalProgress << requestProgress.second;
164 }
147 }
165
148
166 if (fraq > 0) {
149 if (fraq > 0) {
167 finalProgress = finalProgress / fraq;
150 finalProgress = finalProgress / fraq;
168 }
151 }
169
152
170 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
153 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
171 emit dataProvidedProgress(acqIdentifier, finalProgress);
154 emit dataProvidedProgress(acqIdentifier, finalProgress);
172 }
155 }
173 else {
156 else {
174 // This case can happened when a progression is send after the request has been finished.
157 // This case can happened when a progression is send after the request has been finished.
175 // Generaly the case when aborting a request
158 // Generaly the case when aborting a request
176 emit dataProvidedProgress(acqIdentifier, 100.0);
159 emit dataProvidedProgress(acqIdentifier, 100.0);
177 }
160 }
178 }
161 }
179
162
180 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
163 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
181 {
164 {
182 // Retrieves product ID from data: if the value is invalid, no request is made
165 // Retrieves product ID from data: if the value is invalid, no request is made
183 auto productId = data.value(AMDA_XML_ID_KEY).toString();
166 auto productId = data.value(AMDA_XML_ID_KEY).toString();
184 if (productId.isNull()) {
167 if (productId.isNull()) {
185 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
168 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
186 return;
169 return;
187 }
170 }
188
171
189 // Retrieves the data type that determines whether the expected format for the result file is
172 // Retrieves the data type that determines whether the expected format for the result file is
190 // scalar, vector...
173 // scalar, vector...
191 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
174 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
192
175
193 // Gets the server being queried to retrieve the product. It's then used to set the server URL
194 auto productServer = data.value(AMDA_SERVER_KEY).toString();
195
196 // /////////// //
176 // /////////// //
197 // Creates URL //
177 // Creates URL //
198 // /////////// //
178 // /////////// //
199
179
200 auto startDate = dateFormat(dateTime.m_TStart);
180 auto startDate = dateFormat(dateTime.m_TStart);
201 auto endDate = dateFormat(dateTime.m_TEnd);
181 auto endDate = dateFormat(dateTime.m_TEnd);
202
182
203 auto url = QUrl{
183 auto url = QUrl{
204 QString{AMDA_URL_FORMAT}.arg(serverURL(productServer), startDate, endDate, productId)};
184 QString{AMDA_URL_FORMAT}.arg(AmdaServer::instance().url(), startDate, endDate, productId)};
205 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
185 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
206 auto tempFile = std::make_shared<QTemporaryFile>();
186 auto tempFile = std::make_shared<QTemporaryFile>();
207
187
208 // LAMBDA
188 // LAMBDA
209 auto httpDownloadFinished = [this, dateTime, tempFile,
189 auto httpDownloadFinished = [this, dateTime, tempFile,
210 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
190 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
211
191
212 // Don't do anything if the reply was abort
192 // Don't do anything if the reply was abort
213 if (reply->error() == QNetworkReply::NoError) {
193 if (reply->error() == QNetworkReply::NoError) {
214
194
215 if (tempFile) {
195 if (tempFile) {
216 auto replyReadAll = reply->readAll();
196 auto replyReadAll = reply->readAll();
217 if (!replyReadAll.isEmpty()) {
197 if (!replyReadAll.isEmpty()) {
218 tempFile->write(replyReadAll);
198 tempFile->write(replyReadAll);
219 }
199 }
220 tempFile->close();
200 tempFile->close();
221
201
222 // Parse results file
202 // Parse results file
223 if (auto dataSeries
203 if (auto dataSeries
224 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
204 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
225 emit dataProvided(dataId, dataSeries, dateTime);
205 emit dataProvided(dataId, dataSeries, dateTime);
226 }
206 }
227 else {
207 else {
228 /// @todo ALX : debug
208 /// @todo ALX : debug
229 emit dataProvidedFailed(dataId);
209 emit dataProvidedFailed(dataId);
230 }
210 }
231 }
211 }
232 m_AcqIdToRequestProgressMap.erase(dataId);
212 m_AcqIdToRequestProgressMap.erase(dataId);
233 }
213 }
234 else {
214 else {
235 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
215 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
236 emit dataProvidedFailed(dataId);
216 emit dataProvidedFailed(dataId);
237 }
217 }
238
218
239 };
219 };
240 auto httpFinishedLambda
220 auto httpFinishedLambda
241 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
221 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
242
222
243 // Don't do anything if the reply was abort
223 // Don't do anything if the reply was abort
244 if (reply->error() == QNetworkReply::NoError) {
224 if (reply->error() == QNetworkReply::NoError) {
245 auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
225 auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
246
226
247 qCInfo(LOG_AmdaProvider())
227 qCInfo(LOG_AmdaProvider())
248 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
228 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
249 // Executes request for downloading file //
229 // Executes request for downloading file //
250
230
251 // Creates destination file
231 // Creates destination file
252 if (tempFile->open()) {
232 if (tempFile->open()) {
253 // Executes request and store the request for progression
233 // Executes request and store the request for progression
254 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
234 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
255 updateRequestProgress(dataId, request, 0.0);
235 updateRequestProgress(dataId, request, 0.0);
256 emit requestConstructed(request, dataId, httpDownloadFinished);
236 emit requestConstructed(request, dataId, httpDownloadFinished);
257 }
237 }
258 else {
238 else {
259 emit dataProvidedFailed(dataId);
239 emit dataProvidedFailed(dataId);
260 }
240 }
261 }
241 }
262 else {
242 else {
263 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
243 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
264 m_AcqIdToRequestProgressMap.erase(dataId);
244 m_AcqIdToRequestProgressMap.erase(dataId);
265 emit dataProvidedFailed(dataId);
245 emit dataProvidedFailed(dataId);
266 }
246 }
267 };
247 };
268
248
269 // //////////////// //
249 // //////////////// //
270 // Executes request //
250 // Executes request //
271 // //////////////// //
251 // //////////////// //
272
252
273 auto request = std::make_shared<QNetworkRequest>(url);
253 auto request = std::make_shared<QNetworkRequest>(url);
274 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
254 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
275 updateRequestProgress(token, request, 0.0);
255 updateRequestProgress(token, request, 0.0);
276
256
277 emit requestConstructed(request, token, httpFinishedLambda);
257 emit requestConstructed(request, token, httpFinishedLambda);
278 }
258 }
279
259
280 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
260 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
281 std::shared_ptr<QNetworkRequest> request, double progress)
261 std::shared_ptr<QNetworkRequest> request, double progress)
282 {
262 {
283 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress request") << request.get();
263 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress request") << request.get();
284 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
264 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
285 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
265 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
286 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
266 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
287 auto requestProgressMapIt = requestProgressMap.find(request);
267 auto requestProgressMapIt = requestProgressMap.find(request);
288 if (requestProgressMapIt != requestProgressMap.end()) {
268 if (requestProgressMapIt != requestProgressMap.end()) {
289 requestProgressMapIt->second = progress;
269 requestProgressMapIt->second = progress;
290 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
270 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
291 << acqIdentifier << request.get() << progress;
271 << acqIdentifier << request.get() << progress;
292 }
272 }
293 else {
273 else {
294 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
274 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
295 << request.get() << progress;
275 << request.get() << progress;
296 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
276 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
297 }
277 }
298 }
278 }
299 else {
279 else {
300 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
280 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
301 << acqIdentifier << request.get() << progress;
281 << acqIdentifier << request.get() << progress;
302 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
282 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
303 requestProgressMap.insert(std::make_pair(request, progress));
283 requestProgressMap.insert(std::make_pair(request, progress));
304 m_AcqIdToRequestProgressMap.insert(
284 m_AcqIdToRequestProgressMap.insert(
305 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
285 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
306 }
286 }
307 }
287 }
General Comments 0
You need to be logged in to leave comments. Login now