otsdaq_utilities  v2_05_02_indev
ARTDAQConfigurationAPI.js
1 //=====================================================================================
2 //
3 // Created August, 2019
4 // by Ryan Rivera ((rrivera at fnal.gov))
5 //
6 // ARTDAQConfigurationAPI.js
7 //
8 // Requirements:
9 // 1. paste the following:
10 //
11 // <script type="text/JavaScript" src="/WebPath/js/Globals.js"></script>
12 // <script type="text/JavaScript" src="/WebPath/js/Debug.js"></script>
13 // <script type="text/JavaScript" src="/WebPath/js/DesktopContent.js"></script>
14 // <script type="text/JavaScript" src="/WebPath/js/js_lib/ConfiguraitonAPI.js"></script>
15 // <link rel="stylesheet" type="text/css" href="/WebPath/css/ConfigurationAPI.css">
16 // <script type="text/JavaScript" src="/WebPath/js/js_lib/ArtdaqConfiguraitonAPI.js"></script>
17 //
18 // ...anywhere inside the <head></head> tag of a window content html page
19 //
20 //
21 // Example usage: /WebPath/html/ConfigurationGUI_artdaq.html
22 //
23 //=====================================================================================
24 
25 var ARTDAQConfigurationAPI = ARTDAQConfigurationAPI || {}; //define ARTDAQConfigurationAPI namespace
26 
27 if (typeof ConfigurationAPI == 'undefined')
28  alert('ERROR: ConfigurationAPI is undefined! Must include ConfigurationAPI.js before ARTDAQConfigurationAPI.js');
29 
30 //"public" function list:
31 // ARTDAQConfigurationAPI.getArtdaqNodes(responseHandler,modifiedTables)
32 // ARTDAQConfigurationAPI.saveArtdaqNodes(responseHandler,modifiedTables)
33 // ARTDAQConfigurationAPI.getTypeIndex(typeName)
34 // ARTDAQConfigurationAPI.getTypeName(typeIndex)
35 // ARTDAQConfigurationAPI.getShortTypeName(typeIndex)
36 // ARTDAQConfigurationAPI.getFullTypeName(typeIndex)
37 
38 //"public" helpers:
39 
40 //"public" members:
41 
42 //"public" constants:
43 ARTDAQConfigurationAPI.NODE_TYPE_READER = 0;
44 ARTDAQConfigurationAPI.NODE_TYPE_BUILDER = 1;
45 ARTDAQConfigurationAPI.NODE_TYPE_LOGGER = 2;
46 ARTDAQConfigurationAPI.NODE_TYPE_DISPATCHER = 3;
47 ARTDAQConfigurationAPI.NODE_TYPE_MONITOR = 4;
48 ARTDAQConfigurationAPI.NODE_TYPE_ROUTER = 5;
49 ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR = 6;
50 ARTDAQConfigurationAPI.NODE_TYPES = ["reader","builder",
51  "logger","dispatcher","monitor","router","artdaqSupervisor"];
52 ARTDAQConfigurationAPI.NODE_SHORT_TYPE_NAMES = ["Reader","Builder",
53  "Logger","Dispatcher","Monitor","Router","ARTDAQSupervisor"];
54 ARTDAQConfigurationAPI.NODE_FULL_TYPE_NAMES = ["Board Reader","Event Builder",
55  "Data Logger","Dispatcher","Monitor","Routing Master","ARTDAQ Supervisor"];
56 ARTDAQConfigurationAPI.NODE_TYPE_ACRONYM = ["BR","EB",
57  "DL","Di","Mo","RM","AS"];
58 ARTDAQConfigurationAPI.NODE_TYPE_BASE_TABLE = ["ARTDAQBoardReaderTable","ARTDAQEventBuilderTable",
59  "ARTDAQDataLoggerTable","ARTDAQDispatcherTable",
60  "ARTDAQMonitorTable","ARTDAQRoutingMasterTable","ARTDAQSupervisorTable"];
61 ARTDAQConfigurationAPI.DAQ_PARAMETER_TABLE = "ARTDAQDaqParameterTable";
62 ARTDAQConfigurationAPI.DAQ_METRIC_TABLE = "ARTDAQMetricTable";
63 
64 ARTDAQConfigurationAPI.NULL_SUBSYSTEM = "nullDestinationSubsystem";
65 
66 //"private" function list:
67 
68 //"private" constants:
69 
70 
71 //Function definitions:
72 
73 //=====================================================================================
74 //getTypeIndex ~~
75 ARTDAQConfigurationAPI.getTypeIndex = function(typeName)
76 {
77  Debug.log("getTypeIndex " + typeName);
78  t = typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_READER] ? ARTDAQConfigurationAPI.NODE_TYPE_READER:
79  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_BUILDER] ? ARTDAQConfigurationAPI.NODE_TYPE_BUILDER:
80  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_LOGGER] ? ARTDAQConfigurationAPI.NODE_TYPE_LOGGER:
81  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_DISPATCHER] ? ARTDAQConfigurationAPI.NODE_TYPE_DISPATCHER:
82  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_ROUTER] ? ARTDAQConfigurationAPI.NODE_TYPE_ROUTER:
83  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR] ? ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR:
84  (typeName == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_MONITOR] ? ARTDAQConfigurationAPI.NODE_TYPE_MONITOR:-1))))));
85 
86  if(t < 0)
87  {
88  Debug.log("Illegal type name " + typeName +
89  ". Tell admins how you got here!", Debug.HIGH_PRIORITY);
90  return;
91  }
92  return t;
93 } //end getTypeIndex()
94 
95 //=====================================================================================
96 //getTypeName ~~
97 ARTDAQConfigurationAPI.getTypeName = function(typeIndex)
98 {
99  //Debug.log("getTypeName " + typeIndex);
100 
101  if(ARTDAQConfigurationAPI.NODE_TYPES[typeIndex] === undefined)
102  {
103  Debug.log("Illegal type index " + typeIndex +
104  ". Tell admins how you got here!", Debug.HIGH_PRIORITY);
105  return;
106  }
107  return ARTDAQConfigurationAPI.NODE_TYPES[typeIndex];
108 } //end getTypeName()
109 
110 //=====================================================================================
111 //getShortTypeName ~~
112 ARTDAQConfigurationAPI.getShortTypeName = function(typeIndex)
113 {
114  //Debug.log("getShortTypeName " + typeIndex);
115 
116  if(ARTDAQConfigurationAPI.NODE_SHORT_TYPE_NAMES[typeIndex] === undefined)
117  {
118  Debug.log("Illegal type index " + typeIndex +
119  ". Tell admins how you got here!", Debug.HIGH_PRIORITY);
120  return;
121  }
122  return ARTDAQConfigurationAPI.NODE_SHORT_TYPE_NAMES[typeIndex];
123 } //end getShortTypeName()
124 
125 //=====================================================================================
126 //getFullTypeName ~~
127 ARTDAQConfigurationAPI.getFullTypeName = function(typeIndex)
128 {
129  //Debug.log("getFullTypeName " + typeIndex);
130 
131  if(ARTDAQConfigurationAPI.NODE_FULL_TYPE_NAMES[typeIndex] === undefined)
132  {
133  Debug.log("Illegal type index " + typeIndex +
134  ". Tell admins how you got here!", Debug.HIGH_PRIORITY);
135  return;
136  }
137  return ARTDAQConfigurationAPI.NODE_FULL_TYPE_NAMES[typeIndex];
138 } //end getFullTypeName()
139 
140 //=====================================================================================
141 //getArtdaqNodes ~~
142 // get currently active artdaq nodes
143 //
144 // when complete, the responseHandler is called with an object parameter.
145 // on failure, the object will be empty.
146 // on success, the object of Active artdaq nodes
147 // retObj := {}
148 // retObj.<nodeType> = {}
149 // retObj.<nodeType>.<nodeName> = {hostname,subsystemId}
150 // ...
151 // retObj.subsystems = {}
152 // retObj.subsystems.<subsystemId> = {label,sourcesCount,destination}
153 //
154 // <nodeType> = ARTDAQConfigurationAPI.NODE_TYPES := reader, builder, aggregator, dispatcher, monitor
155 //
156 //
157 ARTDAQConfigurationAPI.getArtdaqNodes = function(responseHandler,
158  modifiedTables)
159 {
160  var modifiedTablesListStr = "";
161  for(var i=0;modifiedTables && i<modifiedTables.length;++i)
162  {
163  if(i) modifiedTablesListStr += ",";
164  modifiedTablesListStr += modifiedTables[i].tableName + "," +
165  modifiedTables[i].tableVersion;
166  }
167 
168  //get active configuration group
169  DesktopContent.XMLHttpRequest("Request?RequestType=getArtdaqNodes",
170  "modifiedTables=" + modifiedTablesListStr, //end post data,
171  function(req)
172  {
173  var errArr = DesktopContent.getXMLRequestErrors(req);
174  var errStr = "";
175  for(var i=0;i<errArr.length;++i)
176  {
177  errStr += (i?"\n\n":"") + errArr[i];
178  Debug.log("Error: " + errArr[i], Debug.HIGH_PRIORITY);
179  }
180 
181  responseHandler(localExtractActiveArtdaqNodes(req));
182  },
183  0,0,true //reqParam, progressHandler, callHandlerOnErr
184  ); //end of getActiveTableGroups handler
185 
186  return;
187 
188  //=================
189  function localExtractActiveArtdaqNodes(req)
190  {
191  Debug.log("localExtractActiveArtdaqNodes");
192 
193  //Example xml response:
194  // <artdaqSupervisor value='ARTDAQSupervisor'>
195  // <artdaqSupervisor-contextAddress value='http://correlator2.fnal.gov'/>
196  // <artdaqSupervisor-contextPort value='2016'/>
197  // <subsystem value='nullDestinationSubsystem'/>
198  // <subsystem-id value='0'/>
199  // <subsystem-sourcesCount value='1'/>
200  // <subsystem-destination value='0'/>
201  // <subsystem value='subsystem1'/>
202  // <subsystem-id value='2'/>
203  // <subsystem-sourcesCount value='0'/>
204  // <subsystem-destination value='3'/>
205  // <subsystem value='subsystem2'/>
206  // <subsystem-id value='3'/>
207  // <subsystem-sourcesCount value='1'/>
208  // <subsystem-destination value='0'/>
209  // <reader value='reader0'/>
210  // <reader-hostname value='localhost'/>
211  // <reader-subsystem value='2'/>
212  // <builder value='builder*'>
213  // <builder-multinode value='0'/>
214  // <builder-hostfixedwidth value='3-6'/>
215  // <builder-hostarray value='2'/>
216  // </builder>
217  // <builder value='builder1'/>
218  // <builder-hostname value='localhost'/>
219  // <builder-subsystem value='3'/>
220  // <logger value='logger0'/>
221  // <logger-hostname value='localhost'/>
222  // <logger-subsystem value='3'/>
223  // <dispatcher value='dispatcher0'/>
224  // <dispatcher-hostname value='localhost'/>
225  // <dispatcher-subsystem value='3'/>
226  // </artdaqSupervisor>
227 
228  //can call this at almost all API handlers
229  try
230  {
231  var types = ARTDAQConfigurationAPI.NODE_TYPES;
232 
233  var i,j;
234  var retObj = {};
235 
236 
237  retObj.nodeCount = 0;
238 
239  var artdaqSupervisor = DesktopContent.getXMLNode(
240  req.responseXML,
241  types[ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR]);
242 
243  if(artdaqSupervisor)
244  {
245  //extract all nodes from the artdaq supervisor object
246 
247  for(i=0;i<types.length;++i)
248  {
249  Debug.log("Extracting " + types[i]);
250 
251  retObj[types[i]] = {};
252 
253  if(i == ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR)
254  {
255  //handle artdaq Supervisor node in a special way
256  // because field types are different
257 
258  //add artdaq supervisor object
259  var artdaqSupervisorName = artdaqSupervisor.getAttribute('value');
260 
261  retObj[types[i]][artdaqSupervisorName] = {
262  "status" : DesktopContent.getXMLValue(artdaqSupervisor,
263  types[i] + "-status") | 0, //integer 0 or 1
264  "contextAddress" : DesktopContent.getXMLValue(artdaqSupervisor,
265  types[i] + "-contextAddress"),
266  "contextPort" : DesktopContent.getXMLValue(artdaqSupervisor,
267  types[i] + "-contextPort"),
268  };
269  continue;
270  }
271 
272  var nodes = artdaqSupervisor.getElementsByTagName(
273  types[i]);
274  var statuses = artdaqSupervisor.getElementsByTagName(
275  types[i] + "-status");
276  var hostnames = artdaqSupervisor.getElementsByTagName(
277  types[i] + "-hostname");
278  var subsystemIds = artdaqSupervisor.getElementsByTagName(
279  types[i] + "-subsystem");
280 
281 
282  for(j=0;j<nodes.length;++j)
283  {
284  var multiNodeString = nodes[j].getElementsByTagName(types[i] + "-multinode");
285  var nodeFixedWidth = nodes[j].getElementsByTagName(types[i] + "-nodefixedwidth");
286  var hostArrayString = nodes[j].getElementsByTagName(types[i] + "-hostarray");
287  var hostFixedWidth = nodes[j].getElementsByTagName(types[i] + "-hostfixedwidth");
288 
289  console.log("parameters",multiNodeString,
290  nodeFixedWidth,hostArrayString,hostFixedWidth);
291 
292  var nodeName = nodes[j].getAttribute('value');
293  retObj[types[i]][nodeName] =
294  {
295  "status": statuses[j].getAttribute('value') | 0, //integer 0 or 1
296  "hostname": hostnames[j].getAttribute('value'),
297  "subsystemId": subsystemIds[j].getAttribute('value') | 0, //integer
298  };
299 
300  if(multiNodeString.length)
301  retObj[types[i]][nodeName].multiNodeString = multiNodeString[0].getAttribute('value');
302 
303 
304  if(nodeFixedWidth.length)
305  retObj[types[i]][nodeName].nodeFixedWidth = nodeFixedWidth[0].getAttribute('value') | 0;
306 
307 
308  if(hostArrayString.length)
309  retObj[types[i]][nodeName].hostArrayString = hostArrayString[0].getAttribute('value');
310 
311 
312  if(hostFixedWidth.length)
313  retObj[types[i]][nodeName].hostFixedWidth = hostFixedWidth[0].getAttribute('value') | 0;
314 
315  }
316 
317  Debug.log("Extracted " +
318  nodes.length + " " +
319  types[i]);
320 
321  retObj.nodeCount += nodes.length;
322 
323  } //end type extraction loop
324 
325  //extract all subsystems
326  retObj.subsystems = {};
327  var subsystems = artdaqSupervisor.getElementsByTagName("subsystem");
328  var subsystemIds = artdaqSupervisor.getElementsByTagName(
329  "subsystem" + "-id");
330  var subsystemSourcesCount = artdaqSupervisor.getElementsByTagName(
331  "subsystem" + "-sourcesCount");
332  var subsystemDestination = artdaqSupervisor.getElementsByTagName(
333  "subsystem" + "-destination");
334 
335  for(j=0;j<subsystems.length;++j)
336  {
337  retObj.subsystems[subsystemIds[j].getAttribute('value') | 0 /*integer*/] =
338  {
339  "label": subsystems[j].getAttribute('value'),
340  "sourcesCount": subsystemSourcesCount[j].getAttribute('value'),
341  "destinationId": (subsystemDestination[j].getAttribute('value') | 0) /*integer*/,
342  };
343  }
344 
345 
346  } //end artdaq Supervisor extraction
347  else
348  Debug.log("No artdaq Supervisor found (or there were more than one conflicting). You can manually setup one artdaq Supervisor in the Configuration Tree, " +
349  "or it will be created for you the first time you save your artdaq node configuration.", Debug.WARN_PRIORITY);
350 
351  Debug.log("Total nodes extracted " +
352  retObj.nodeCount);
353 
354  if(retObj.nodeCount == 0)
355  Debug.log("Successful node extraction, but no artdaq nodes found!", Debug.WARN_PRIORITY);
356 
357  }
358  catch(e)
359  {
360  Debug.log("Error extracting active artdaq nodes: " + e, Debug.HIGH_PRIORITY);
361  return undefined;
362  }
363 
364  return retObj;
365  } // end localExtractActiveArtdaqNodes()
366 
367 } // end getArtdaqNodes()
368 
369 //====================================================================================
370 //saveArtdaqNodes ~~
371 // save artdaq nodes and subsystems to active groups (with modified tables)
372 // nodeObj := {}
373 // nodeObj.<nodeType> = {}
374 // nodeObj.<nodeType>.<nodeName> =
375 // {originalName,status,hostname,subsystemName,
376 // (nodeArrString),(hostnameArrString),(nodeNameFixedWidth),(hostnameFixedWidth)}
377 //
378 // <nodeType> = ARTDAQConfigurationAPI.NODE_TYPES := reader, builder, aggregator, dispatcher, monitor
379 //
380 // subsystemObj = {}
381 // subsystemObj.<subsystemName> = {destinationName}
382 //
383 ARTDAQConfigurationAPI.saveArtdaqNodes = function(nodesObject, subsystemsObject, responseHandler,
384  modifiedTables)
385 {
386  console.log("nodesObject",nodesObject);
387  console.log("subsystemsObject",subsystemsObject);
388 
389  var modifiedTablesListStr = "";
390  for(var i=0;modifiedTables && i<modifiedTables.length;++i)
391  {
392  if(i) modifiedTablesListStr += ",";
393  modifiedTablesListStr += modifiedTables[i].tableName + "," +
394  modifiedTables[i].tableVersion;
395  }
396 
397  var nodeString = "";
398  var subsystemString = "";
399 
400  for(var i in nodesObject)
401  {
402  if(i == ARTDAQConfigurationAPI.NODE_TYPES[ARTDAQConfigurationAPI.NODE_TYPE_SUPERVISOR])
403  continue; //skip supervisor type.. it is handled automatically
404 
405  nodeString += encodeURIComponent(i) + ":";
406  for(var j in nodesObject[i])
407  {
408  nodeString += encodeURIComponent(j) + "=";
409 
410  //map undefined to "" so it is not confused with an actual record UID
411  nodeString += encodeURIComponent(nodesObject[i][j].originalName === undefined?"":nodesObject[i][j].originalName) + ",";
412 
413  nodeString += (nodesObject[i][j].status?1:0) + ",";
414  nodeString += encodeURIComponent(nodesObject[i][j].hostname) + ",";
415  nodeString += encodeURIComponent(nodesObject[i][j].subsystemName) + "";
416 
417  //now optional node parameters
418  if(nodesObject[i][j].nodeArrString)
419  nodeString += "," + encodeURIComponent(nodesObject[i][j].nodeArrString);
420  if(nodesObject[i][j].nodeNameFixedWidth)
421  nodeString += "," + encodeURIComponent("nnfw," + nodesObject[i][j].nodeNameFixedWidth);
422  if(nodesObject[i][j].hostnameArrString)
423  nodeString += "," + encodeURIComponent(nodesObject[i][j].hostnameArrString);
424  if(nodesObject[i][j].hostnameFixedWidth)
425  nodeString += "," + encodeURIComponent("hnfw," + nodesObject[i][j].hostnameFixedWidth);
426 
427  nodeString += ";"; //end node
428  }
429  nodeString += "|"; //end artdaq type
430  }
431  for(var i in subsystemsObject)
432  {
433  subsystemString += encodeURIComponent(i) + ":";
434  subsystemString += encodeURIComponent(subsystemsObject[i].destinationName);
435  subsystemString += ";"; //end subsystem
436  }
437 
438  console.log("nodeString",nodeString);
439  console.log("subsystemStr",subsystemString);
440 
441  //save nodes and subsystems to server
442  DesktopContent.XMLHttpRequest("Request?RequestType=saveArtdaqNodes",
443  "modifiedTables=" + modifiedTablesListStr +
444  "&nodeString=" + nodeString +
445  "&subsystemString=" + subsystemString, //end post data,
446  function(req)
447  {
448  console.log("response",req);
449 
450  var errArr = DesktopContent.getXMLRequestErrors(req);
451  var errStr = "";
452  for(var i=0;i<errArr.length;++i)
453  {
454  errStr += (i?"\n\n":"") + errArr[i];
455  Debug.log("Error: " + errArr[i], Debug.HIGH_PRIORITY);
456  }
457 
458  if(errArr.length) return; // do not proceed on error
459  //else call response handler
460  responseHandler(req);
461 
462  },
463  0,0,true //reqParam, progressHandler, callHandlerOnErr
464  ); //end of getActiveTableGroups handler
465 
466  return;
467 
468 } // end saveArtdaqNodes()
469 
470 
471 
472 
473 
474 
475 
476 
477 
478 
479 
480 
481 
482 
483 
484 
485 
486 
487