Line data Source code
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 126 : ClassImp(AliHLTHOMERProxyHandler)
39 :
40 : /*
41 : * ---------------------------------------------------------------------------------
42 : * Constructor / Destructor
43 : * ---------------------------------------------------------------------------------
44 : */
45 :
46 : //##################################################################################
47 0 : AliHLTHOMERProxyHandler::AliHLTHOMERProxyHandler() :
48 0 : fRealm(kHLT),
49 0 : fXmlRpcResponse(""),
50 0 : 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 0 : }
57 :
58 : //##################################################################################
59 0 : AliHLTHOMERProxyHandler::~AliHLTHOMERProxyHandler() {
60 : // see header file for class documentation
61 :
62 0 : }
63 :
64 : //##################################################################################
65 : Int_t AliHLTHOMERProxyHandler::Initialize() {
66 : // see header file for class documentation
67 0 : IdentifyRealm();
68 0 : 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 0 : fSourceList = srcList;
84 :
85 0 : iResult = RequestXmlRpcResponse();
86 :
87 0 : if (!iResult)
88 0 : iResult = ProcessXmlRpcResponse();
89 :
90 0 : if (iResult < 0) {
91 0 : HLTError("Filling SourceList failed.");
92 : }
93 :
94 0 : 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 0 : TString hostIP(gSystem->GetHostByName(gSystem->HostName()).GetHostAddress());
122 :
123 0 : HLTInfo(hostIP.Data());
124 :
125 0 : if ( hostIP.Contains("10.162.") )
126 0 : fRealm = kHLT;
127 0 : else if ( hostIP.Contains("10.160.") || hostIP.Contains("10.161.") )
128 0 : fRealm = kACR;
129 0 : else if ( hostIP.Contains("129.206.") )
130 0 : fRealm = kKIP;
131 0 : else if ( hostIP.Contains("137.138")
132 0 : || hostIP.Contains("128.141")
133 0 : || hostIP.Contains("127.0.")
134 0 : || hostIP.Contains("192.168")
135 : )
136 0 : fRealm = kGPN;
137 : else {
138 0 : fRealm = kLoc;
139 : }
140 :
141 : //fRealm = kLoc;
142 :
143 : return;
144 0 : }
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 0 : TSocket *socket = new TSocket(fgkHOMERProxyNode[fRealm], proxyPort);
164 0 : if ( ! socket->IsValid() ) {
165 0 : HLTWarning(Form("Failed to create socket to %s:%d,",fgkHOMERProxyNode[fRealm], proxyPort));
166 0 : HLTWarning(Form("trying %s:%d now.", fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
167 :
168 0 : socket = new TSocket(fgkHOMERProxyNode[fRealm+kHOMERRealmsMax], proxyPort);
169 0 : if ( ! socket->IsValid() ) {
170 0 : HLTError(Form("Failed to create socket to %s:%d and %s:%d.",
171 : fgkHOMERProxyNode[fRealm], proxyPort,
172 : fgkHOMERProxyNode[fRealm+kHOMERRealmsMax],proxyPort));
173 :
174 0 : HLTWarning(Form("trying %s:%d now.",
175 : fgkHOMERProxyNode[kLoc],proxyPort));
176 0 : socket = new TSocket(fgkHOMERProxyNode[kLoc], proxyPort);
177 0 : if ( ! socket->IsValid() ) {
178 0 : 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 0 : fRealm = -1;
183 0 : return -1;
184 : }
185 : else {
186 0 : fRealm = kLoc;
187 : }
188 0 : }
189 : else
190 0 : fRealm = fRealm+kHOMERRealmsMax;
191 : }
192 :
193 : // -- send request
194 : // -----------------
195 :
196 0 : 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 0 : iResult = socket->SendRaw( reqMsg, strlen(reqMsg) );
205 0 : if ( iResult < 1 ||
206 0 : iResult != static_cast<Int_t>(strlen(reqMsg))) {
207 0 : HLTError(Form("Error sending! -- send length %d -- msg length %d.", iResult, static_cast<Int_t>(strlen(reqMsg)) ));
208 0 : socket->Close();
209 0 : return iResult;
210 : }
211 :
212 : // -- receive answer
213 : // -------------------
214 :
215 : const Int_t bufferSize = 1024;
216 0 : Char_t buffer[bufferSize];
217 :
218 : Bool_t isXmlRpc = kFALSE;
219 :
220 0 : fXmlRpcResponse = "";
221 :
222 : // -- loop for getting full xmlRPC response
223 0 : while(1) {
224 :
225 : Int_t bufferLength = 0;
226 :
227 : // -- loop for reading until end of line
228 0 : while (1) {
229 :
230 0 : iResult = socket->RecvRaw(&buffer[bufferLength], 1);
231 0 : if ( iResult < 0) {
232 0 : HLTError("Error reading form socket.");
233 0 : socket->Close();
234 0 : return iResult;
235 : }
236 :
237 : // -- Checking for end of line
238 0 : if ( buffer[bufferLength] == 10 ) {
239 0 : buffer[bufferLength] = 0;
240 : break;
241 : }
242 :
243 0 : ++bufferLength;
244 : }
245 :
246 0 : TString bufferString(buffer);
247 :
248 : // -- Checking for start of XML response
249 0 : if ( bufferString.BeginsWith("<?xml") )
250 0 : isXmlRpc = kTRUE;
251 :
252 : // -- Append the xml response
253 0 : if (isXmlRpc) {
254 0 : fXmlRpcResponse.Append(bufferString);
255 : }
256 :
257 : // -- Checking for end of XML response
258 0 : if( ! bufferString.CompareTo("</methodResponse>") )
259 0 : break;
260 0 : }
261 :
262 : // -- close socket
263 0 : socket->Close();
264 :
265 0 : return 0;
266 0 : }
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 0 : TDOMParser xmlParser;
278 0 : 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 0 : TString infoMsg = Form("XMLResponse: %s",fXmlRpcResponse.Data());
283 0 : HLTInfo(infoMsg.Data());
284 :
285 0 : iResult = xmlParser.ParseBuffer(fXmlRpcResponse.Data(), fXmlRpcResponse.Length());
286 0 : if ( iResult < 0 ) {
287 0 : HLTError(Form("Parsing buffer with error: %s",
288 : xmlParser.GetParseCodeMessage(xmlParser.GetParseCode()) ));
289 :
290 :
291 0 : return iResult;
292 : }
293 :
294 0 : TXMLNode * node = xmlParser.GetXMLDocument()->GetRootNode()->
295 : GetChildren()->GetChildren()->GetChildren()->GetChildren();
296 :
297 0 : if ( strcmp( node->GetNodeName(), "string" ) ) {
298 0 : HLTError("No node 'string' in XmlRpcResponse.");
299 0 : return -1;
300 : }
301 :
302 : // -- Parse Content
303 : // ------------------
304 :
305 : // -- Get Content
306 0 : TString xmlContent(node->GetText() );
307 :
308 : HLTDebug(Form("XMLContent: %s",xmlContent.Data()));
309 :
310 0 : iResult = xmlParser.ParseBuffer(xmlContent.Data(), xmlContent.Length());
311 0 : if ( iResult < 0 ) {
312 0 : HLTError(Form("Parsing buffer with error: %s",
313 : xmlParser.GetParseCodeMessage(xmlParser.GetParseCode()) ));
314 :
315 0 : return iResult;
316 : }
317 :
318 0 : if ( !xmlParser.GetXMLDocument()->GetRootNode()->HasChildren() ) {
319 0 : HLTWarning("No Services active.");
320 0 : return 1;
321 : }
322 :
323 : // -- Loop over all service nodes
324 0 : TXMLNode* serviceNode = xmlParser.GetXMLDocument()->GetRootNode()->GetChildren();
325 : TXMLNode* prevServiceNode = NULL;
326 :
327 0 : do {
328 : prevServiceNode = serviceNode;
329 :
330 : // -- Add service to list
331 0 : iResult = AddService( serviceNode->GetChildren() );
332 0 : if ( iResult > 0 ) {
333 0 : HLTWarning("Incomplete Service not added.");
334 : iResult = 0;
335 0 : }
336 0 : } while ( ( serviceNode = prevServiceNode->GetNextNode() ) && !iResult );
337 :
338 :
339 :
340 : return iResult;
341 0 : }
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 0 : 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 0 : TString hostname = "";
364 : Int_t port = 0;
365 0 : TString dataType = "";
366 0 : TString dataOrigin = "";
367 0 : TString dataSpecification = "";
368 :
369 : TXMLNode* prevInnerNode = NULL;
370 :
371 : // -- Retrieve hostname and port
372 : // -------------------------------
373 :
374 0 : do {
375 : prevInnerNode = innerNode;
376 :
377 0 : if ( ! strcmp(innerNode->GetNodeName(), "text" ) )
378 : continue;
379 :
380 : // -- hostname
381 0 : if ( ! strcmp( innerNode->GetNodeName(), "address") ) {
382 0 : HLTInfo(Form(" > %s ++ %s", innerNode->GetNodeName(), innerNode->GetText() ));
383 0 : hostname = innerNode->GetText();
384 : }
385 0 : else if ( ! strcmp( innerNode->GetNodeName(), "port") ) {
386 0 : HLTInfo(Form(" > %s ++ %s", innerNode->GetNodeName(), innerNode->GetText() ));
387 0 : TString portS(innerNode->GetText());
388 0 : if ( portS.IsDigit() )
389 0 : port = portS.Atoi();
390 : else {
391 0 : HLTError(Form("Port %s is not a digit.", portS.Data()));
392 : iResult = -1;
393 : }
394 0 : }
395 0 : } while ( ( innerNode = prevInnerNode->GetNextNode() ) && !iResult );
396 :
397 :
398 : // -- Change hostame from service with proxy, if outside HLT
399 0 : if ( fRealm != kHLT && fRealm != kHLT+kHOMERRealmsMax )
400 0 : hostname = fgkHOMERProxyNode[fRealm];
401 :
402 :
403 : // -- Get Data Specifications from blocks
404 : // ----------------------------------------
405 :
406 : do {
407 : prevInnerNode = serviceNode;
408 :
409 0 : if ( strcmp( serviceNode->GetNodeName(), "blocks") )
410 : continue;
411 :
412 0 : TXMLNode* blocks = serviceNode->GetChildren();
413 :
414 0 : if ( ! blocks ) {
415 0 : HLTError("No blocks present");
416 0 : return 1;
417 : }
418 :
419 0 : TXMLNode* blockNode = blocks->GetNextNode();
420 : TXMLNode* prevBlockNode = NULL;
421 :
422 0 : if ( ! blockNode ) {
423 0 : HLTError("No block present in the blocks tag");
424 0 : return 1;
425 : }
426 :
427 : // -- blocks loop
428 :
429 : do {
430 : prevBlockNode = blockNode;
431 :
432 0 : if ( strcmp( blockNode->GetNodeName(), "block") )
433 : continue;
434 :
435 0 : TXMLNode *dataNode = blockNode->GetChildren();
436 : TXMLNode *prevDataNode = NULL;
437 :
438 0 : if ( ! dataNode ) {
439 0 : HLTError("No data specification tags present in block tag.");
440 0 : return 1;
441 : }
442 : // -- data spec loop
443 :
444 : do {
445 : prevDataNode = dataNode;
446 :
447 0 : if ( ! strcmp(dataNode->GetNodeName(), "text" ) )
448 : continue;
449 :
450 0 : HLTInfo(Form(" %s ++ %s", dataNode->GetNodeName(), dataNode->GetText() ));
451 :
452 0 : if ( ! strcmp( dataNode->GetNodeName(), "dataorigin") ) {
453 0 : dataOrigin = dataNode->GetText();
454 : }
455 0 : else if ( ! strcmp( dataNode->GetNodeName(), "datatype") ) {
456 0 : dataType = dataNode->GetText();
457 : }
458 0 : else if ( ! strcmp( dataNode->GetNodeName(), "dataspecification") ) {
459 0 : dataSpecification = dataNode->GetText();
460 : }
461 0 : } 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 0 : if ( hostname.IsNull() || !port || dataOrigin.IsNull() ||
470 0 : dataType.IsNull() || dataSpecification.IsNull() ) {
471 0 : 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 0 : return 1;
475 : }
476 :
477 : // -- Create new source
478 : // ----------------------
479 :
480 0 : AliHLTHOMERSourceDesc * source = new AliHLTHOMERSourceDesc();
481 0 : source->SetService( hostname, port, dataOrigin, dataType, dataSpecification );
482 :
483 0 : fSourceList->Add( source );
484 :
485 0 : HLTInfo(Form( "New Source added : %s", source->GetSourceName().Data()));
486 :
487 0 : } while ( ( blockNode = prevBlockNode->GetNextNode() ) && !iResult );
488 :
489 :
490 : // -- blocks loop
491 :
492 0 : } while ( ( serviceNode = prevInnerNode->GetNextNode() ) && !iResult );
493 :
494 0 : return iResult;
495 0 : }
496 :
497 :
|