]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTHOMERProxyHandler.cxx
from Timo: added attempt at connecting to localhost if others don't work
[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   "localhost",
118   "portal-dcs1.internal", 
119   "alihlt-dcs1.cern.ch",
120   "alihlt-vobox1.cern.ch",
121   "alihlt-gw1.kip.uni-heidelberg.de",
122   "localhost"
123 };
124
125 //##################################################################################
126 void AliHLTHOMERProxyHandler::IdentifyRealm() {
127   // see header file for class documentation
128
129   TString hostIP(gSystem->GetHostByName(gSystem->HostName()).GetHostAddress());
130
131   if ( hostIP.Contains("10.162.") )
132     fRealm = kHLT;
133   else if ( hostIP.Contains("10.160.") || hostIP.Contains("10.161.") )
134     fRealm = kACR;
135   else if ( hostIP.Contains("129.206.") )
136     fRealm = kKIP;
137   else  if ( hostIP.Contains("137.138") 
138              || hostIP.Contains("128.141") 
139              || hostIP.Contains("127.0.") 
140              )
141     fRealm = kGPN;
142   else {
143     fRealm = kLoc;
144   }
145
146   return;
147 }
148
149 /*
150  * ---------------------------------------------------------------------------------
151  *                        Proxy Communication - private
152  * ---------------------------------------------------------------------------------
153  */
154
155 //##################################################################################
156 Int_t AliHLTHOMERProxyHandler::RequestXmlRpcResponse() {
157   // see header file for class documentation
158
159   Int_t iResult = 0;
160
161   // -- open socket
162   // ----------------
163
164   Int_t proxyPort = 19999;
165
166   TSocket *socket = new TSocket(fgkHOMERProxyNode[fRealm], proxyPort);
167   if ( ! socket->IsValid() ) {
168     HLTWarning(Form("Failed to create socket to %s:%d,",fgkHOMERProxyNode[fRealm], proxyPort));
169     HLTWarning(Form("trying %s:%d now.", fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
170
171     socket = new TSocket(fgkHOMERProxyNode[fRealm+kHOMERRealmsMax], proxyPort);
172     if ( ! socket->IsValid() ) {
173       HLTError(Form("Failed to create socket to %s:%d and %s:%d.",
174                     fgkHOMERProxyNode[fRealm], proxyPort,
175                     fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
176
177       HLTWarning(Form("trying %s:%d now.",
178                       fgkHOMERProxyNode[kLoc],proxyPort));
179       socket = new TSocket(fgkHOMERProxyNode[kLoc], proxyPort);
180       if ( ! socket->IsValid() ) {
181         HLTError(Form("Failed to create socket to %s:%d , %s:%d and %s:%d.",
182                       fgkHOMERProxyNode[fRealm], proxyPort,
183                       fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort,
184                       fgkHOMERProxyNode[kLoc], proxyPort));
185         fRealm = -1;
186         return -1;
187       }
188       else {
189         fRealm = kLoc;
190       }
191     }
192     else
193       fRealm = fRealm+kHOMERRealmsMax;
194   }
195
196   // -- send request
197   // -----------------
198
199   Char_t reqMsg[] = "PUT / HTTP/1.1\r\n\
200 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\
201 Host: localhost:10000\r\n\
202 Accept: */*\r\n\
203 Content-type: text/xml\r\n\
204 Content-Length: 68\r\n\
205 \r\n<methodCall><methodName>getTcpDumpServices</methodName></methodCall>\r\n";
206
207   iResult = socket->SendRaw( reqMsg, strlen(reqMsg) );
208   if ( iResult < 1 || 
209        iResult !=  static_cast<Int_t>(strlen(reqMsg))) {
210     HLTError(Form("Error sending! -- send length %d  -- msg length %d.", iResult, static_cast<Int_t>(strlen(reqMsg)) ));
211     socket->Close();
212     return iResult;
213   }
214   
215   // -- receive answer
216   // -------------------
217
218   const Int_t bufferSize = 1024;
219   Char_t buffer[bufferSize];
220
221   Bool_t isXmlRpc = kFALSE;
222
223   fXmlRpcResponse = "";
224
225   // -- loop for getting full xmlRPC response
226   while(1) {
227
228     Int_t bufferLength = 0;
229     
230     // -- loop for reading until end of line
231     while (1) {
232
233       iResult = socket->RecvRaw(&buffer[bufferLength], 1);
234       if ( iResult < 0) {
235         HLTError(Form("Error reading form socket."));
236         socket->Close();
237         return iResult;
238       }
239             
240       // -- Checking for  end of line
241       if ( buffer[bufferLength] == 10 ) {
242         buffer[bufferLength] = 0;
243         break;
244       }
245       
246       ++bufferLength;
247     }
248
249     TString bufferString(buffer);
250
251     // -- Checking for start of XML response
252     if ( bufferString.BeginsWith("<?xml") )
253       isXmlRpc = kTRUE;
254
255     // -- Append the xml response
256     if (isXmlRpc) {
257       fXmlRpcResponse.Append(bufferString);
258     }
259
260     // -- Checking for end of XML response
261     if( ! bufferString.CompareTo("</methodResponse>") ) 
262       break;
263   }
264   
265   // -- close socket
266   socket->Close();
267
268   return 0;
269 }
270
271 //##################################################################################
272 Int_t AliHLTHOMERProxyHandler::ProcessXmlRpcResponse() {
273   // see header file for class documentation
274
275   Int_t iResult = 0;
276
277   // -- Parse XML RPC Response
278   // ---------------------------
279
280   TDOMParser xmlParser;
281   xmlParser.SetValidate(kFALSE);
282
283   HLTDebug(Form("XMLResponse: %s",fXmlRpcResponse.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(Form("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(Form("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(Form("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(Form(">> 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(Form("No blocks present"));
416       return 1;
417     }
418       
419     TXMLNode* blockNode = blocks->GetNextNode();
420     TXMLNode* prevBlockNode = NULL;
421
422     if ( ! blockNode ) {
423       HLTError(Form("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(Form("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