3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTOnlineConfiguration.h
20 /// @author Matthias Richter
21 /// @author Lars Christian Raae
23 /// @brief Description of the HLT online configuration
30 #include <TDOMParser.h>
34 #include <TObjString.h>
36 #include "AliHLTDAQ.h"
37 #include "AliHLTOnlineConfiguration.h"
38 #include "AliHLTComponentConfiguration.h"
40 /** ROOT macro for the implementation of ROOT specific class methods */
41 ClassImp(AliHLTOnlineConfiguration)
43 AliHLTOnlineConfiguration::AliHLTOnlineConfiguration()
50 // see header file for class documentation
52 // refer to README to build package
54 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
58 AliHLTOnlineConfiguration::~AliHLTOnlineConfiguration()
63 int AliHLTOnlineConfiguration::LoadConfiguration(const char* filename)
65 /// load configuration from file
73 in.seekg(0, std::ios::end );
74 filesize = in.tellg();
75 in.seekg(0, std::ios::beg);
77 char * content = new char[filesize];
78 in.read(content, filesize);
81 fXMLBuffer.Adopt(filesize, content);
88 int AliHLTOnlineConfiguration::Compress()
90 /// compress the xml buffer
95 int AliHLTOnlineConfiguration::Uncompress()
97 /// compress the xml buffer
102 int AliHLTOnlineConfiguration::Parse()
104 /// parse the xml buffer
107 if (TestBit(kLoaded)) {
109 TDOMParser *domParser = new TDOMParser();
110 domParser->SetValidate(false);
111 Int_t parsecode = domParser->ParseBuffer(fXMLBuffer.GetArray(), fXMLSize);
113 HLTError("Configuration XML invalid or not well-formed (error code %d)", parsecode);
117 if ((doc = domParser->GetXMLDocument()) && doc->GetRootNode()) {
118 iResult = ParseConfiguration(doc->GetRootNode());
130 int AliHLTOnlineConfiguration::ParseConfiguration(TXMLNode* node)
132 /// parse xml configuration
136 if (node && node->GetChildren()) {
137 node = node->GetChildren();
138 for (; node; node = node->GetNextNode()) {
139 if (node->GetNodeType() == TXMLNode::kXMLElementNode) {
140 if (strcmp(node->GetNodeName(), "Proc") == 0) {
142 const char* type = 0;
143 if (node->HasAttributes()) {
144 TList* attrList = node->GetAttributes();
146 TIter next(attrList);
147 while ((attr=(TXMLAttr*)next()))
148 if (strcmp(attr->GetName(), "ID") == 0) {
149 id = attr->GetValue();
150 } else if (strcmp(attr->GetName(), "type") == 0) {
151 type = attr->GetValue();
154 if (id && type && node->GetChildren()) {
155 if (ParseEntry(node->GetChildren(), id, type) == 0) {
160 HLTError("Configuration component missing ID attribute");
163 HLTError("Configuration component missing type attribute");
166 HLTError("Empty configuration component %s", id);
173 HLTError("Configuration did not contain any (valid) elements");
178 HLTError("Configuration was empty");
183 int AliHLTOnlineConfiguration::ParseEntry(TXMLNode* node, const char* id,
186 /// Parse XML configuration entry.
190 const char* source = 0;
193 for (; node; node = node->GetNextNode()) {
194 if (node->GetNodeType() == TXMLNode::kXMLElementNode) {
195 if (strcmp(node->GetNodeName(), "Cmd") == 0) {
196 if (!cmd) // Use only the first (non-empty) <Cmd> element
197 cmd = node->GetText();
199 else if (strcmp(node->GetNodeName(), "Node") == 0) {
200 if (!nodes.IsNull()) nodes += " "; nodes += node->GetText();
202 else if (strcmp(node->GetNodeName(), "Parent") == 0) {
203 source = node->GetText();
204 if (sources.Contains(source)) {
206 HLTError("Configuration component %s has duplicate <Parent> element %s",
210 if (!sources.IsNull()) sources += " "; sources += node->GetText();
218 HLTError("Configuration component %s does not contain <Cmd> element", id);
220 else if (cmd == strstr(cmd, "AliRootWrapperSubscriber"))
221 iResult = ParseStandardComponent(id, type, cmd, sources, nodes);
222 else if (cmd == strstr(cmd, "RORCPublisher"))
223 iResult = ParseRORCPublisher(id, type, cmd, sources, nodes);
224 else if (cmd == strstr(cmd, "TCPDumpSubscriber"))
225 iResult = ParseTCPDumpSubscriber(id, type, cmd, sources, nodes);
226 else if (cmd == strstr(cmd, "Relay"))
227 iResult = ParseRelay(id, type, cmd, sources, nodes);
228 else if (cmd == strstr(cmd, "HLTOutFormatter"))
229 iResult = ParseHLTOutFormatter(id, type, cmd, sources, nodes);
230 else if (cmd == strstr(cmd, "HLTOutWriterSubscriber"))
231 iResult = ParseHLTOutWriterSubscriber(id, type, cmd, sources, nodes);
234 HLTError("Configuration component %s contains unknown <Cmd> element", id);
241 int AliHLTOnlineConfiguration::ParseStandardComponent(const char* id,
242 const char* type, const char* cmd, TString& sources, TString& nodes)
244 /// Parse standard component configuration
247 if (strcmp(type, "prc") != 0) {
249 HLTError("Configuration component %s has invalid type %s (expected prc)",
253 // Parse component command
254 const char* compid="";
255 const char* complib="";
257 bool hasArgs = false;
258 char* cmdcopy = new char[strlen(cmd)+1];
259 if (!cmdcopy) return -ENOMEM;
260 cmdcopy[strlen(cmd)]=0;
261 strncpy(cmdcopy, cmd, strlen(cmd));
262 strtok(cmdcopy, " -"); // Skip "AliRootWrapperSubscriber"
264 while (((strtmp = strtok(0, " -")))) {
265 if (strcmp(strtmp, "componentid") == 0)
266 compid = strtok(0, " -");
267 else if (strcmp(strtmp, "componentargs") == 0)
269 else if (strcmp(strtmp, "componentlibrary") == 0)
270 complib = strtok(0, " -");
273 // Parse component arguments
274 int start = strstr(cmd, "-componentargs") + strlen("-componentargs") + 2
276 int arglen = strcspn(cmd+start, "\"");
277 // Verify that we have the actual limits of the componentargs
278 if ((size_t)(start+arglen) < strlen(cmd) && cmd[start-1] == '\"' &&
279 cmd[start+arglen] == '\"')
281 compargs = new char[arglen+1];
282 strncpy(compargs, cmd + start, arglen);
283 compargs[arglen] = '\0';
288 HLTError("Configuration component %s is missing component id", id);
292 HLTError("Configuration component %s is missing component library", id);
294 if (hasArgs && !compargs) {
296 HLTError("Configuration component %s is missing component arguments", id);
299 AliHLTComponentConfiguration* entry = new AliHLTComponentConfiguration(id,
300 compid, sources.Data(), compargs);
301 entry->SetOnlineCommand(cmd);
302 entry->SetComponentLibrary(complib);
303 entry->SetNodeNames(nodes.Data());
304 fConfEntryList.Add(entry);
312 int AliHLTOnlineConfiguration::ParseRORCPublisher(const char* id,
313 const char* type, const char* cmd, TString& sources, TString& nodes)
315 /// Parse RORCPublisher configuration
318 if (strcmp(type, "src") != 0) {
320 HLTError("Configuration component %s has invalid type %s (expected src)",
324 const char compid[] = "AliRawReaderPublisher";
325 const char complib[] = "libAliHLTUtil.so";
326 // Parse (and validate) component command
328 int res = sscanf(cmd, "RORCPublisher -slot %*d %*d %*d %*d -rorcinterface %*d -sleep "
329 "-sleeptime %*d -maxpendingevents %*d -alicehlt -ddlid %d", &ddlID);
332 HLTError("Configuration component %s has <Cmd> element of unknown format\n"
333 "Expected format: RORCPublisher -slot %%d %%d %%d %%d -rorcinterface %%d "
334 "-sleep -sleeptime %%d -maxpendingevents %%d -alicehlt -ddlid %%d", id);
338 Int_t detectorID = AliHLTDAQ::DetectorIDFromDdlID(ddlID, ddlIndex);
339 string HLTOrigin = AliHLTDAQ::HLTOrigin(detectorID);
340 string HLTSpecification = AliHLTDAQ::HLTSpecificationFromDdlID(ddlID);
342 compargs.Form("-minid %d -datatype 'DDL_RAW ' '%s' -dataspec %s",
343 ddlID, HLTOrigin.c_str(), HLTSpecification.c_str());
344 AliHLTComponentConfiguration* entry = new AliHLTComponentConfiguration(id,
345 compid, sources.Data(), compargs.Data());
346 entry->SetOnlineCommand(cmd);
347 entry->SetComponentLibrary(complib);
348 entry->SetNodeNames(nodes.Data());
349 fConfEntryList.Add(entry);
355 int AliHLTOnlineConfiguration::ParseTCPDumpSubscriber(const char* id,
356 const char* type, const char* /* cmd */, TString& /* sources */,
357 TString& /* nodes */)
359 /// Parse TCPDumpSubscriber configuration
361 if (strcmp(type, "snk") != 0) {
363 HLTError("Configuration component %s has invalid type %s (expected snk)",
369 int AliHLTOnlineConfiguration::ParseRelay(const char* id, const char* type,
370 const char* cmd, TString& sources, TString& nodes)
372 /// Parse Relay configuration
375 if (strcmp(type, "prc") != 0) {
377 HLTError("Configuration component %s has invalid type %s (expected prc)",
381 const char compid[] = "BlockFilter";
382 const char complib[] = "libAliHLTUtil.so";
383 const char* compargs = "";
384 if (strcmp(cmd, "Relay") == 0) {
385 AliHLTComponentConfiguration* entry = new AliHLTComponentConfiguration(id,
386 compid, sources.Data(), compargs);
387 entry->SetOnlineCommand(cmd);
388 entry->SetComponentLibrary(complib);
389 entry->SetNodeNames(nodes.Data());
390 fConfEntryList.Add(entry);
394 HLTError("Configuration component %s has <Cmd> element of unknown type "
401 int AliHLTOnlineConfiguration::ParseHLTOutFormatter(const char* id,
402 const char* type, const char* /* cmd */, TString& sources,
403 TString& /* nodes */)
405 /// Parse HLTOutFormatter configuration
408 if (strcmp(type, "prc") != 0) {
410 HLTError("Configuration component %s has invalid type %s (expected prc)",
414 fDefaultChains = sources;
419 int AliHLTOnlineConfiguration::ParseHLTOutWriterSubscriber(const char* id,
420 const char* type, const char* /* cmd */, TString& /* sources */,
421 TString& /* nodes */)
423 /// Parse HLTOutWriterSubscriber configuration
426 if (strcmp(type, "snk") != 0) {
428 HLTError("Configuration component %s has invalid type %s (expected snk)",
434 TString AliHLTOnlineConfiguration::GetComponentLibraries()
436 /// get component libraries
439 AliHLTComponentConfiguration* pConf;
441 TIter next(&fConfEntryList);
442 while ((pConf=(AliHLTComponentConfiguration*)next())) {
443 complib = pConf->GetComponentLibrary();
444 if (!result.Contains(complib)) {
445 if (!result.IsNull()) result+=" "; result+=complib;
451 void AliHLTOnlineConfiguration::Print(const char* options) const
453 /// overloaded from TObject, print info
454 const UInt_t defaultSampleSize = 200;
456 TObject::Print(options);
457 printf("Configuration loaded: %s\n", (TestBit(kLoaded) ? "YES" : "NO"));
458 TString opt = options;
460 Bool_t buffer = opt.Contains("buffer");
461 Bool_t parsed = opt.Contains("parsed");
463 if (TestBit(kLoaded)) {
465 char configuration[fXMLSize + 1];
466 strncpy(configuration, fXMLBuffer.GetArray(), fXMLSize);
467 printf("%s\n\n", configuration);
469 AliHLTComponentConfiguration* pConf;
470 TIter next(&fConfEntryList);
471 while ((pConf=(AliHLTComponentConfiguration*)next())) {
472 pConf->Print("status");
475 Int_t sampleSize = (defaultSampleSize <= fXMLSize) ?
476 defaultSampleSize : fXMLSize;
477 char sample[sampleSize];
478 for (int i = 0; i < sampleSize - 1; i++)
479 sample[i] = fXMLBuffer.At(i);
480 sample[sampleSize - 1] = '\0';
481 printf("%s...\n\n", sample);
485 printf("XML size (uncompressed): %d\n", fXMLSize);
486 printf("Configuration compressed: %s\n", (TestBit(kCompressed) ? "YES" : "NO"));
487 printf("Configuration parsed: %s\n", (TestBit(kParsed) ? "YES" : "NO"));
488 printf("Parsed configuration entries: %d\n", fConfEntryList.GetSize());
489 printf("Default chains: %s\n", fDefaultChains.Data());
492 void AliHLTOnlineConfiguration::Dump() const
494 /// overloaded from TObject, more crude data dump
499 void AliHLTOnlineConfiguration::Clear(Option_t * option)
501 /// overloaded from TObject, clear object
503 TObject::Clear(option);
504 fConfEntryList.Delete();
505 fDefaultChains.Clear();
509 ResetBit(kCompressed);
513 TObject * AliHLTOnlineConfiguration::Clone(const char *newname) const
515 /// overloaded from TObject, clone object
517 return TObject::Clone(newname);
520 void AliHLTOnlineConfiguration::Copy(TObject &object) const
522 /// overloaded from TObject, copy object
524 TObject::Copy(object);
527 void AliHLTOnlineConfiguration::Draw(Option_t */*option*/)
529 /// overloaded from TObject, draw graph of the configuration