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