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