]> git.uio.no Git - u/mrichter/AliRoot.git/blame - SHUTTLE/AliDCSClient.cxx
Improved access to AliITSgeom in reconstruction
[u/mrichter/AliRoot.git] / SHUTTLE / AliDCSClient.cxx
CommitLineData
73abe331 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/*
17$Log$
18Revision 1.1.1.1 2005/09/12 22:11:40 byordano
19SHUTTLE package
20
21Revision 1.3 2005/08/30 10:53:23 byordano
22some more descriptions added
23
24*/
25
26//
27// This class represents the AliDCSClient.
28// The client used for data retrieval from DCS server.
29// There are two way for retrieving data from the server.
30// 1) asking for DP (DataPoint) - usually changed frequently.
31// 2) asking for Alias (Alias) - alias should be the same through whole
32// experimnet.
33//
34// There are two type of read operations:
35// Asking for single alias/dp or asking for set of aliases/dp
36//
37// In case of ServerError the coresponding error code and
38// error string (description) could be got by GetServerErrorCode() and
39// GetServerErrorString()
40//
41
42#include "AliDCSClient.h"
43
44#include "AliDCSValue.h"
45#include "AliLog.h"
46
47#include <TList.h>
48#include <TMap.h>
49#include <TObjString.h>
50#include <TSystem.h>
51
52ClassImp(AliDCSClient)
53
54const Int_t AliDCSClient::fgkBadState;
55
56const Int_t AliDCSClient::fgkInvalidParameter;
57
58const Int_t AliDCSClient::fgkTimeout;
59
60const Int_t AliDCSClient::fgkBadMessage;
61
62const Int_t AliDCSClient::fgkCommError;
63
64const Int_t AliDCSClient::fgkServerError;
65
66const char* AliDCSClient::fgkBadStateString = "BadState";
67
68const char* AliDCSClient::fgkInvalidParameterString = "InvalidParameter";
69
70const char* AliDCSClient::fgkTimeoutString = "Timeout";
71
72const char* AliDCSClient::fgkBadMessageString = "BadMessage";
73
74const char* AliDCSClient::fgkCommErrorString = "CommunicationError";
75
76const char* AliDCSClient::fgkServerErrorString = "ServerError";
77
78AliDCSClient::AliDCSClient(const char* host, Int_t port, UInt_t timeout,
79 Int_t retries):
80 fSocket(NULL), fTimeout(timeout), fRetries(retries),
81 fServerErrorCode(AliDCSMessage::kNoneError), fServerError("")
82{
83 //
84 // host: DCS server host
85 // port: DCS server port
86 // timeout: in case of communication error or socket read/write this
87 // timeout will be used before the next try is made.
88 // retries: the number of retries after which the connection is
89 // is considered as invalid and error is returned.
90 //
91
92 Int_t tries = 0;
93
94 while (tries < fRetries) {
95 fSocket = new TSocket(host, port);
96 if (fSocket->IsValid()) {
97 AliDebug(1, Form("Connected to %s:%d", host, port));
98 fSocket->SetOption(kNoBlock, 1);
99 break;
100 }
101
102 AliDebug(1, Form("Connection timeout! tries <%d> ...", tries));
103
104 delete fSocket;
105 fSocket = NULL;
106
107 gSystem->Sleep(fTimeout);
108 tries ++;
109 }
110}
111
112AliDCSClient::~AliDCSClient() {
113 if (fSocket) {
114 Close();
115 delete fSocket;
116 }
117}
118
119Int_t AliDCSClient::SendBuffer(const char* buffer, Int_t size) {
120
121 Int_t sentSize = 0;
122 Int_t tries = 0;
123
124 while (sentSize < size && tries < fRetries) {
125
126 Int_t sResult = fSocket->Select(TSocket::kWrite, fTimeout);
127
128 if (sResult == 0) {
129 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
130 tries ++;
131 continue;
132
133 } else if (sResult < 0) {
134 AliDebug(1, Form("Communication error <%d>!",
135 fSocket->GetErrorCode()));
136 return AliDCSClient::fgkCommError;
137 }
138
139 sResult = fSocket->SendRaw(buffer + sentSize, size - sentSize,
140 kDontBlock);
141
142 if (sResult > 0) {
143 sentSize += sResult;
144 } else {
145 AliDebug(1, Form("Communication error <%d>!",
146 fSocket->GetErrorCode()));
147 return AliDCSClient::fgkCommError;
148 }
149 }
150
151 if (tries == fRetries) {
152 return AliDCSClient::fgkTimeout;
153 }
154
155 return sentSize;
156}
157
158Int_t AliDCSClient::ReceiveBuffer(char* buffer, Int_t size) {
159
160 Int_t receivedSize = 0;
161 Int_t tries = 0;
162
163 while (receivedSize < size && tries < fRetries) {
164
165 Int_t sResult = fSocket->Select(TSocket::kRead, fTimeout);
166
167 if (sResult == 0) {
168 AliDebug(1, Form("Timeout! tries <%d> ...", tries));
169 tries ++;
170 continue;
171
172 } else if (sResult < 0) {
173 AliDebug(1, Form("Communication error <%d>",
174 fSocket->GetErrorCode()));
175 return AliDCSClient::fgkCommError;
176 }
177
178 sResult = fSocket->RecvRaw(buffer + receivedSize,
179 size - receivedSize, kDontBlock);
180
181 if (sResult > 0) {
182 receivedSize += sResult;
183 } else {
184 AliDebug(1, Form("Communication error <%d>",
185 fSocket->GetErrorCode()));
186 return AliDCSClient::fgkCommError;
187 }
188 }
189
190 if (tries == fRetries) {
191 return AliDCSClient::fgkTimeout;
192 }
193
194 return receivedSize;
195}
196
197Int_t AliDCSClient::SendMessage(AliDCSMessage& message) {
198
199 message.StoreToBuffer();
200
201 AliDebug(2, "Sending message.\n");
202 message.Print();
203
204 return SendBuffer(message.GetMessage(), message.GetMessageSize());
205}
206
207Int_t AliDCSClient::ReceiveMessage(AliDCSMessage& message) {
208
209 char header[HEADER_SIZE];
210
211 Int_t sResult;
212
213 if ((sResult = ReceiveBuffer(header, HEADER_SIZE)) < 0) {
214 AliDebug(1, Form("Can't receive message header! Reason: %s",
215 GetErrorString(sResult)));
216 return sResult;
217 }
218
219 if (!message.SetRawHeader(header)) {
220 return AliDCSClient::fgkBadMessage;
221 }
222
223 if ((sResult = ReceiveBuffer(message.GetBody(),
224 message.GetBodySize())) < 0) {
225
226 AliDebug(1, Form("Can't receive message body! Reason: %s",
227 GetErrorString(sResult)));
228 return sResult;
229 }
230
231 message.LoadFromBuffer();
232
233 AliDebug(2, "Message received.");
234 message.Print();
235
236 return HEADER_SIZE + sResult;
237}
238
239Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
240 const char* reqString, UInt_t startTime, UInt_t endTime, TList& result)
241{
242 if (!IsConnected()) {
243 AliError("Not connected!");
244 return AliDCSClient::fgkBadState;
245 }
246
247 Int_t sResult;
248 AliDCSMessage requestMessage;
249 requestMessage.CreateRequestMessage(reqType, startTime, endTime,
250 reqString);
251
252 if ((sResult = SendMessage(requestMessage)) < 0) {
253 AliError(Form("Can't send request message! Reason: %s",
254 GetErrorString(sResult)));
255 Close();
256 return sResult;
257 }
258
259 sResult = ReceiveValueSet(result);
260
261 Close();
262
263 return sResult;
264}
265
266Int_t AliDCSClient::GetValues(AliDCSMessage::RequestType reqType,
267 UInt_t startTime, UInt_t endTime, TMap& result)
268{
269 if (!IsConnected()) {
270 AliError("Not connected!");
271 return AliDCSClient::fgkBadState;
272 }
273
274 AliDCSMessage multiRequestMessage;
275 multiRequestMessage.CreateMultiRequestMessage(reqType,
276 startTime, endTime);
277
278 TList requests;
279
280 TIter iter(&result);
281 TObjString* aRequest;
282
283 // copy request strings to temporary TList because
284 // TMap doesn't guarantee the order of elements!!!
285 while ((aRequest = (TObjString*) iter.Next())) {
286 requests.Add(aRequest);
287 if (!multiRequestMessage.AddRequestString(aRequest->String()))
288 {
289 return AliDCSClient::fgkInvalidParameter;
290 }
291 }
292
293 Int_t sResult;
294 if ((sResult = SendMessage(multiRequestMessage)) < 0) {
295 AliError(Form("Can't send request message! Reason: %s",
296 GetErrorString(sResult)));
297 Close();
298 return sResult;
299 }
300
301 result.SetOwner(0);
302 result.Clear();
303
304 TIter reqIter(&requests);
305 while ((aRequest = (TObjString*) reqIter.Next())) {
306 TList* resultSet = new TList();
307 resultSet->SetOwner(1);
308
309 if ((sResult = ReceiveValueSet(*resultSet)) < 0) {
310 AliError(Form("Can't get values for %s!" ,
311 aRequest->String().Data()));
312
313 delete resultSet;
314 break;
315 }
316
317 result.Add(aRequest, resultSet);
318 }
319
320 if (sResult < 0) {
321 result.DeleteValues();
322 result.Clear();
323
324 requests.Delete();
325 } else {
326 result.SetOwner(1);
327 }
328
329 Close();
330
331 return sResult;
332}
333
334Int_t AliDCSClient::ReceiveValueSet(TList& result) {
335
336 Int_t sResult;
337
338 AliDCSMessage responseMessage;
339 if ((sResult = ReceiveMessage(responseMessage)) < 0) {
340 AliError(Form("Can't receive response message! Reason: %s",
341 GetErrorString(sResult)));
342 return sResult;
343 }
344
345 UInt_t valueCount;
346
347 if (responseMessage.GetType() == AliDCSMessage::kCount) {
348 valueCount = responseMessage.GetCount();
349
350 } else if (responseMessage.GetType() == AliDCSMessage::kError) {
351 fServerErrorCode = responseMessage.GetErrorCode();
352 fServerError = responseMessage.GetErrorString();
353
354 return AliDCSClient::fgkServerError;
355
356 } else {
357 AliError("Bad message type received!");
358 return AliDCSClient::fgkBadMessage;
359 }
360
361 UInt_t receivedValues = 0;
362
363 AliSimpleValue::Type valueType = AliSimpleValue::kInvalid;
364
365 while (receivedValues < valueCount) {
366
367 AliDCSMessage message;
368
369 if ((sResult = ReceiveMessage(message)) < 0) {
370 AliError(Form("Can't receive message! Reason: %s",
371 GetErrorString(sResult)));
372 return sResult;
373 }
374
375 if (message.GetType() == AliDCSMessage::kResultSet) {
376
377 if (valueType == AliSimpleValue::kInvalid) {
378 valueType = message.GetSimpleValueType();
379 } else {
380 if (valueType != message.GetSimpleValueType()) {
381 AliError("Unexpected value type!");
382 return AliDCSClient::fgkBadMessage;
383 }
384 }
385
386 receivedValues += message.GetValues(result);
387
388 if (receivedValues > valueCount) {
389 AliError("Message contains more values than expected!");
390 return AliDCSClient::fgkBadMessage;
391 }
392
393 } else if (message.GetType() == AliDCSMessage::kError) {
394 fServerErrorCode =
395 responseMessage.GetErrorCode();
396 fServerError = responseMessage.GetErrorString();
397
398 return AliDCSClient::fgkServerError;
399 } else {
400 AliError("Bad message type received!");
401 return AliDCSClient::fgkBadMessage;
402 }
403 }
404
405 return receivedValues;
406}
407
408Int_t AliDCSClient::GetDPValues(const char* dpName, UInt_t startTime,
409 UInt_t endTime, TList& result)
410{
411 //
412 // Reads a values from the server which correspond to this
413 // DataPoint (dpName) in time interval (startTime - endTime).
414 // result: Collection of AliDCSValue which contains the read values.
415 //
416 // Returns:
417 // If >= 0 , the number of values read.
418 // if < 0, the error code which has occured during the read.
419 //
420
421 return GetValues(AliDCSMessage::kDPName,
422 dpName, startTime, endTime, result);
423}
424
425Int_t AliDCSClient::GetAliasValues(const char* alias, UInt_t startTime,
426 UInt_t endTime, TList& result)
427{
428 //
429 // Reads a values from the server which correspond to this
430 // alias (alias) in time interval (startTime - endTime).
431 // result: Collection of AliDCSValue which contains the read values.
432 //
433 // Returns:
434 // If >= 0 , the number of values read.
435 // if < 0, the error code which has occured during the read.
436 //
437
438 return GetValues(AliDCSMessage::kAlias,
439 alias, startTime, endTime, result);
440}
441
442Int_t AliDCSClient::GetDPValues(UInt_t startTime, UInt_t endTime,
443 TMap& result)
444{
445 //
446 // For every key of 'result' (which must be TObjString)
447 // reads a valueSet. The key represents particular DataPoint to be read.
448 // For all DataPoints time interval (startTime - endTime) is used.
449 // After the read, the correspoding value for every key is a
450 // TList - collection of AliDCSValue, or result is an empty map in
451 // case of error.
452 //
453 // Returns:
454 // If >= 0 , the number of values read.
455 // if < 0, the error code which has occured during the read.
456 //
457
458 return GetValues(AliDCSMessage::kDPName, startTime, endTime, result);
459}
460
461Int_t AliDCSClient::GetAliasValues(UInt_t startTime, UInt_t endTime,
462 TMap& result)
463{
464 //
465 // For every key of 'result' (which must be TObjString)
466 // reads a valueSet. The key represents particular Alias to be read.
467 // For all aliases time interval (startTime - endTime) is used.
468 // After the read, the correspoding value for every key is a
469 // TList - collection of AliDCSValue, or result is an empty map in
470 // case of error.
471 //
472 // Returns:
473 // If >= 0 , the number of values read.
474 // if < 0, the error code which has occured during the read.
475 //
476
477 return GetValues(AliDCSMessage::kAlias, startTime, endTime, result);
478}
479
480Bool_t AliDCSClient::IsConnected() {
481 //
482 // Returns kTRUE if there is a valid connection to the server.
483 //
484
485 if (fSocket) {
486 return fSocket->IsValid();
487 }
488
489 return kFALSE;
490}
491
492void AliDCSClient::Close() {
493 //
494 // Close the connection.
495 //
496
497 if (fSocket) {
498 fSocket->Close();
499 }
500}
501
502const char* AliDCSClient::GetErrorString(Int_t code) {
503 //
504 // Returns a short string describing the error code.
505 // code: the error code.
506 //
507
508
509 switch (code) {
510 case AliDCSClient::fgkBadState:
511 return AliDCSClient::fgkBadStateString;
512
513 case AliDCSClient::fgkInvalidParameter:
514 return AliDCSClient::fgkInvalidParameterString;
515
516 case AliDCSClient::fgkTimeout:
517 return AliDCSClient::fgkTimeoutString;
518
519 case AliDCSClient::fgkBadMessage:
520 return AliDCSClient::fgkBadMessageString;
521
522 case AliDCSClient::fgkCommError:
523 return AliDCSClient::fgkCommErrorString;
524
525 case AliDCSClient::fgkServerError:
526 return AliDCSClient::fgkServerErrorString;
527
528 default:
529 AliErrorGeneral("AliDCSClient::GetErrorString",
530 "Unknown error code!");
531 return "UnknownCode";
532 }
533}
534