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