]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTHOMERProxyHandler.cxx
* Bugfixes for 64Bit - 32Bit machines in the Source/Block Desc
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTHOMERProxyHandler.cxx
1 //-*- Mode: C++ -*-
2 // $Id: AliHLTHOMERProxyHandler.cxx  $
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /** @file   AliHLTHOMERProxyHandler.cxx
20     @author Jochen Thaeder
21     @date
22     @brief  HOMER proxy handler for HomerManger
23 */
24
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #if __GNUC__>= 3
32    using namespace std;
33 #endif
34
35 #include "TDOMParser.h"
36 #include "TSocket.h"
37 #include "TSystem.h"
38 // -- -- -- -- -- -- -- 
39 #include "AliHLTHOMERProxyHandler.h"
40 // -- -- -- -- -- -- -- 
41
42 ClassImp(AliHLTHOMERProxyHandler)
43
44 /*
45  * ---------------------------------------------------------------------------------
46  *                            Constructor / Destructor
47  * ---------------------------------------------------------------------------------
48  */
49
50 //##################################################################################
51 AliHLTHOMERProxyHandler::AliHLTHOMERProxyHandler() :
52   fRealm(kHLT),
53   fXmlRpcResponse(""),
54   fSourceList(NULL) {
55   // see header file for class documentation
56   // or
57   // refer to README to build package
58   // or
59   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
60 }
61
62 //##################################################################################
63 AliHLTHOMERProxyHandler::~AliHLTHOMERProxyHandler() {
64   // see header file for class documentation
65
66 }
67
68 //##################################################################################
69 Int_t AliHLTHOMERProxyHandler::Initialize() {
70   // see header file for class documentation
71
72   Int_t iResult = 0 ;
73
74   IdentifyRealm();
75
76   return iResult;
77 }
78
79 /*
80  * ---------------------------------------------------------------------------------
81  *                             Source List - public
82  * ---------------------------------------------------------------------------------
83  */
84
85 //##################################################################################
86 Int_t AliHLTHOMERProxyHandler::FillSourceList(TList *srcList) {
87   // see header file for class documentation
88
89   Int_t iResult = 0;
90
91   fSourceList = srcList;
92
93   iResult = RequestXmlRpcResponse();
94
95   if (!iResult)
96     iResult = ProcessXmlRpcResponse();
97
98   if (iResult < 0) {
99     HLTError(Form("Filling SourceList failed."));
100   }
101
102   return iResult;
103 }
104
105 /*
106  * ---------------------------------------------------------------------------------
107  *                        Realms - private
108  * ---------------------------------------------------------------------------------
109  */
110
111 //##################################################################################
112 const Char_t *AliHLTHOMERProxyHandler::fgkHOMERProxyNode[] = { 
113   "portal-dcs0.internal", 
114   "alihlt-dcs0.cern.ch",
115   "alihlt-vobox0.cern.ch",
116   "alihlt-gw0.kip.uni-heidelberg.de",
117   "portal-dcs1.internal", 
118   "alihlt-dcs1.cern.ch",
119   "alihlt-vobox1.cern.ch",
120   "alihlt-gw1.kip.uni-heidelberg.de"
121 };
122
123 //##################################################################################
124 void AliHLTHOMERProxyHandler::IdentifyRealm() {
125   // see header file for class documentation
126
127   TString hostIP(gSystem->GetHostByName(gSystem->HostName()).GetHostAddress());
128
129   if ( hostIP.Contains("10.162.") )
130     fRealm = kHLT;
131   else if ( hostIP.Contains("10.160.") || hostIP.Contains("10.161.") )
132     fRealm = kACR;
133   else if ( hostIP.Contains("129.206.") )
134     fRealm = kKIP;
135   else 
136     fRealm = kGPN;
137   
138   return;
139 }
140
141 /*
142  * ---------------------------------------------------------------------------------
143  *                        Proxy Communication - private
144  * ---------------------------------------------------------------------------------
145  */
146
147 //##################################################################################
148 Int_t AliHLTHOMERProxyHandler::RequestXmlRpcResponse() {
149   // see header file for class documentation
150
151   Int_t iResult = 0;
152
153   // -- open socket
154   // ----------------
155
156   Int_t proxyPort = 19999;
157
158   TSocket *socket = new TSocket(fgkHOMERProxyNode[fRealm], proxyPort);
159   if ( ! socket->IsValid() ) {
160     HLTWarning(Form("Failed to create socket to %s:%d,",fgkHOMERProxyNode[fRealm], proxyPort));
161     HLTWarning(Form("trying %s:%d now.", fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
162
163     socket = new TSocket(fgkHOMERProxyNode[fRealm+kHOMERRealmsMax], proxyPort);
164     if ( ! socket->IsValid() ) {
165       HLTError(Form("Failed to create socket to %s:%d and %s:%d.",
166                     fgkHOMERProxyNode[fRealm], proxyPort,
167                     fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
168
169       fRealm = -1;
170       return -1;
171     }
172     else
173       fRealm = fRealm+kHOMERRealmsMax;
174   }
175
176   // -- send request
177   // -----------------
178
179   Char_t reqMsg[] = "PUT / HTTP/1.1\r\n\
180 User-Agent: curl/7.18.0 (x86_64-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n\
181 Host: localhost:10000\r\n\
182 Accept: */*\r\n\
183 Content-type: text/xml\r\n\
184 Content-Length: 68\r\n\
185 \r\n<methodCall><methodName>getTcpDumpServices</methodName></methodCall>\r\n";
186
187   iResult = socket->SendRaw( reqMsg, strlen(reqMsg) );
188   if ( iResult < 1 || 
189        iResult !=  static_cast<Int_t>(strlen(reqMsg))) {
190     HLTError(Form("Error sending! -- send length %d  -- msg length %d.", iResult, static_cast<Int_t>(strlen(reqMsg)) ));
191     socket->Close();
192     return iResult;
193   }
194   
195   // -- receive answer
196   // -------------------
197
198   const Int_t bufferSize = 1024;
199   Char_t buffer[bufferSize];
200
201   Bool_t isXmlRpc = kFALSE;
202
203   fXmlRpcResponse = "";
204
205   // -- loop for getting full xmlRPC response
206   while(1) {
207
208     Int_t bufferLength = 0;
209     
210     // -- loop for reading until end of line
211     while (1) {
212
213       iResult = socket->RecvRaw(&buffer[bufferLength], 1);
214       if ( iResult < 0) {
215         HLTError(Form("Error reading form socket."));
216         socket->Close();
217         return iResult;
218       }
219             
220       // -- Checking for  end of line
221       if ( buffer[bufferLength] == 10 ) {
222         buffer[bufferLength] = 0;
223         break;
224       }
225       
226       ++bufferLength;
227     }
228
229     TString bufferString(buffer);
230
231     // -- Checking for start of XML response
232     if ( bufferString.BeginsWith("<?xml") )
233       isXmlRpc = kTRUE;
234
235     // -- Append the xml response
236     if (isXmlRpc) {
237       fXmlRpcResponse.Append(bufferString);
238     }
239
240     // -- Checking for end of XML response
241     if( ! bufferString.CompareTo("</methodResponse>") ) 
242       break;
243   }
244   
245   // -- close socket
246   socket->Close();
247
248   return 0;
249 }
250
251 //##################################################################################
252 Int_t AliHLTHOMERProxyHandler::ProcessXmlRpcResponse() {
253   // see header file for class documentation
254
255   Int_t iResult = 0;
256
257   // -- Parse XML RPC Response
258   // ---------------------------
259
260   TDOMParser xmlParser;
261   xmlParser.SetValidate(kFALSE);
262
263   HLTDebug(Form("XMLResponse: %s",fXmlRpcResponse.Data()));
264   
265   iResult = xmlParser.ParseBuffer(fXmlRpcResponse.Data(), fXmlRpcResponse.Length());
266   if ( iResult < 0 ) {
267     HLTError(Form("Parsing buffer with error: %s", 
268                   xmlParser.GetParseCodeMessage(xmlParser.GetParseCode()) ));
269     
270
271     return iResult;
272   }
273
274   TXMLNode * node = xmlParser.GetXMLDocument()->GetRootNode()->
275     GetChildren()->GetChildren()->GetChildren()->GetChildren();
276   
277   if ( strcmp( node->GetNodeName(), "string" ) ) {
278     HLTError(Form("No node 'string' in XmlRpcResponse."));
279     return -1;
280   }
281
282   // -- Parse Content
283   // ------------------
284
285   // -- Get Content
286   TString xmlContent(node->GetText() );
287
288   HLTDebug(Form("XMLContent: %s",xmlContent.Data()));
289
290   iResult = xmlParser.ParseBuffer(xmlContent.Data(), xmlContent.Length());
291   if ( iResult < 0 ) {
292     HLTError(Form("Parsing buffer with error: %s", 
293                   xmlParser.GetParseCodeMessage(xmlParser.GetParseCode()) ));
294
295     return iResult;
296   }
297   
298   if ( !xmlParser.GetXMLDocument()->GetRootNode()->HasChildren() ) {
299     HLTWarning(Form("No Services active."));
300     return 1;
301   }
302
303   // -- Loop over all service nodes
304   TXMLNode* serviceNode = xmlParser.GetXMLDocument()->GetRootNode()->GetChildren();
305   TXMLNode* prevServiceNode = NULL;
306   
307   do {
308     prevServiceNode = serviceNode;
309
310     // -- Add service to list
311     iResult = AddService( serviceNode->GetChildren() );
312     if ( iResult > 0 ) {
313       HLTWarning(Form("Incomplete Service not added."));
314       iResult = 0;
315     }
316   } while ( ( serviceNode = prevServiceNode->GetNextNode() ) && !iResult );
317
318
319
320   return iResult;
321 }
322
323 /*
324  * ---------------------------------------------------------------------------------
325  *                            Source Resolving - private
326  * ---------------------------------------------------------------------------------
327  */
328
329 //##################################################################################
330 Int_t AliHLTHOMERProxyHandler::AddService(TXMLNode *innerNode) {
331   // see header file for class documentation
332
333   Int_t iResult = 0;
334
335   HLTInfo(Form(">> New service"));    
336
337   TXMLNode* serviceNode = innerNode;
338
339   // -- Loop over all service properties and 
340   //    read them from the service tag
341   // -----------------------------------------
342
343   TString hostname          = "";
344   Int_t   port              = 0;
345   TString dataType          = "";
346   TString dataOrigin        = "";
347   TString dataSpecification = "";
348
349   TXMLNode* prevInnerNode = NULL;
350
351   // -- Retrieve hostname and port
352   // -------------------------------
353
354   do {
355     prevInnerNode = innerNode;
356     
357     if ( ! strcmp(innerNode->GetNodeName(), "text" ) )
358       continue;
359         
360     // -- hostname
361     if ( ! strcmp( innerNode->GetNodeName(), "address") ) {
362       HLTInfo(Form("  > %s ++ %s", innerNode->GetNodeName(), innerNode->GetText() ));
363       hostname = innerNode->GetText();
364     }
365     else if ( ! strcmp( innerNode->GetNodeName(), "port") ) {
366       HLTInfo(Form("  > %s ++ %s", innerNode->GetNodeName(), innerNode->GetText() ));
367       TString portS(innerNode->GetText());
368       if ( portS.IsDigit() )
369         port = portS.Atoi();
370       else {
371         HLTError(Form("Port %s is not a digit.", portS.Data()));
372         iResult = -1;
373       }
374     }
375   } while ( ( innerNode = prevInnerNode->GetNextNode() ) && !iResult );
376
377
378   // -- Change hostame from service with proxy, if outside HLT
379   if ( fRealm != kHLT || fRealm != kHLT+kHOMERRealmsMax )
380     hostname = fgkHOMERProxyNode[fRealm];
381
382
383   // -- Get Data Specifications from blocks
384   // ----------------------------------------
385
386   do {
387     prevInnerNode = serviceNode;
388
389     if ( strcmp( serviceNode->GetNodeName(), "blocks") )
390       continue;
391  
392     TXMLNode* blocks = serviceNode->GetChildren();
393
394     if ( ! blocks ) {
395       HLTError(Form("No blocks present"));
396       return 1;
397     }
398       
399     TXMLNode* blockNode = blocks->GetNextNode();
400     TXMLNode* prevBlockNode = NULL;
401
402     if ( ! blockNode ) {
403       HLTError(Form("No block present in the blocks tag"));
404       return 1;
405     }
406       
407     // -- blocks loop 
408     
409     do {
410       prevBlockNode = blockNode;
411       
412       if ( strcmp( blockNode->GetNodeName(), "block") )
413         continue;
414
415       TXMLNode *dataNode = blockNode->GetChildren();
416       TXMLNode *prevDataNode = NULL;
417
418       if ( ! dataNode ) {
419         HLTError(Form("No data specification tags present in block tag."));
420         return 1;
421       }
422       // -- data spec loop
423       
424       do {
425         prevDataNode = dataNode;
426
427         if ( ! strcmp(dataNode->GetNodeName(), "text" ) )
428           continue;
429
430         HLTInfo(Form(" %s ++ %s", dataNode->GetNodeName(), dataNode->GetText() ));      
431
432         if ( ! strcmp( dataNode->GetNodeName(), "dataorigin") ) {
433           dataOrigin = dataNode->GetText();
434         }
435         else if ( ! strcmp( dataNode->GetNodeName(), "datatype") ) {
436           dataType = dataNode->GetText();
437         }
438         else if ( ! strcmp( dataNode->GetNodeName(), "dataspecification") ) {
439           dataSpecification = dataNode->GetText();    
440         }
441       } while ( ( dataNode = prevDataNode->GetNextNode() ) && !iResult );
442       
443       // -- data spec loop
444
445       // -- Check the service properties
446       // ---------------------------------
447       
448       // -- Check for completeness of the source properties
449       if ( hostname.IsNull() || !port || dataOrigin.IsNull() ||
450            dataType.IsNull() || dataSpecification.IsNull() ) {
451         HLTWarning(Form("Service provides not all values:\n\thostname\t\t %s\n\tport\t\t\t %d\n\tdataorigin\t\t %s\n\tdatatype\t\t %s\n\tdataspecification\t 0x%08X", 
452                         hostname.Data(), port, dataOrigin.Data(), dataType.Data(), dataSpecification.Atoi()));
453         
454         return 1;
455       }
456
457       // -- Create new source
458       // ----------------------
459       
460       AliHLTHOMERSourceDesc * source = new AliHLTHOMERSourceDesc();
461       source->SetService( hostname, port, dataOrigin, dataType, dataSpecification );
462       
463       fSourceList->Add( source );
464       
465       HLTInfo(Form( "New Source added : %s", source->GetSourceName().Data()));
466
467     } while ( ( blockNode = prevBlockNode->GetNextNode() ) && !iResult );
468
469
470     // -- blocks loop
471     
472   } while ( ( serviceNode = prevInnerNode->GetNextNode() ) && !iResult );
473   
474   return iResult;
475 }
476
477