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