MonitorNode

MonitorNode is a monitor container hosting dynamic monitor instances on demand. It listens to an input XQueue for JMS messages as requests to monitor certain occurrences. If the message contains a request for a new monitor, MonitorNode will create a monitor instance according to the ruleset and the content of the message. Upon success, the incoming message will be routed to the outlink of bypass. If it fails to create the monitor instance, the message will be routed to the outlink of failure. If there is no ruleset to handle the message, it will be routed to the outlink of nohit. Meanwhile, MonitorNode periodically dispatches all active monitors as tasks to the outlink of pool. On the other end of the outlink, a number of MonitorPersisters will be listening on the outlink for tasks. They will run those monitor tasks and update the results on the tasks. Each task will be collected by MonitorNode for evaluations on its result. MonitorNode will apply the predefined EventPattern of the ruleset to check the result. If the result is as expected, MonitorNode will generate a new message with the result and routes it to the outlink of done. Then the monitor instance will be terminated and destroyed.

MonitorNode contains a number of predefined rulesets. These rulesets categorize messages into non-overlapping groups via the filters. Therefore, each rule defines a unique message group. If a ruleset is not of bypass, it is supposed to define a template to construct properties for new monitor instances. It also contains multiple parameters for the node to manage active monitor instances. For example, TimeToLive specifies the lifetime in seconds of the new monitor instance. Once the instance passes that time span, MonitorNode will escalate the final event and terminates the instance. Option is another parameter which controls when to deliver the original request. By default, it is zero and there is no wait on the final event. If it is 1, MonitorNode will hold the request and waits until the final event is escalated. Heartbeat determines how often to run the monitor instance. The non-bypass rulesets may also have a list of EventPatterns to determine when to escalate the final event for the occurrence and when to terminate the monitor instance. The total number of active monitors is stored into the RULE_PEND field. For those messages falling off all defined rulesets, MonitorNode always creates an extra ruleset, nohit, to handle them. Therefore all the nohit messages will be routed to the outlink of nohit.

You are free to choose any names for the five fixed outlinks. But MonitorNode always assumes the first outlink for pool, the second for done, the third for bypass, the fourth for failure and the last for nohit.

Apart from the common properties, there are two implementation specific properties for MonitorNode.
Property Name Data Type Requirement Description Examples
Heartbeat integer optional interval in sec to dispatch 120 (default: 60)
RCField string optional name of the field to store return code
where Heartbeat determines how frequently to run those monitors. If StringProperty is defined on the node level, it will be used to build the summary on cached messages for display.

The monitor operation is executed via the pre-defined rulesets. Therefore, the configuration of the rulesets is critical to the operations of MonitorNode. Here are complete properties of rulesets for MonitorNode.
Property Name Data Type Requirement Description Examples
Name alphanumeric with no spaces mandatory name of the ruleset event
TimeToLive integer optional max number seconds for a monitor to be active 36000 (default: 0 for evergreen)
Heartbeat integer optional interval to dispatch monitor tasks 300 (default is set by the node)
Capacity integer optional max number of active monitors 24 (default: 64)
Option integer of 0 or 1 optional on-wait option controling when to deliver the original messages 1 (default: 0 for no wait)
MaxRetry integer optional max retry on failed tasks 1 (default: 2)
EventPattern list optional list of EventPattern groups on monitor events to terminate monitors see example
Monitor map mandatory for monitors only configuration template of monitors see example
JMSPropertyGroup list optional list of pattern groups on properties to select messages see example
XJMSPropertyGroup list optional list of pattern groups on properties to exclude messages see example
PatternGroup list optional list of pattern groups on body to select messages see example
XPatternGroup list optional list of pattern groups on body to exclude messages see example
StringProperty map optional for logging on properties of messages see example
DisplayMask integer optional display mask for logging 6 (default: 0)
where Monitor is the configuration template for monitor instances with certain variables. The node will resolve those variables based on the data extracted from the request message. You can find many examples on MonitorAgent page.

Here is an example of MonitorNode:

{
  "Name": "node_monitor",
  "ClassName": "org.qbroker.node.MonitorNode",
  "Operation": "monitor",
  "LinkName": "monitor",
  "Capacity": "32",
  "DisplayMask": "0",
  "Heartbeat": "300",
  "Debug": "31",
  "Ruleset": [{
    "Name": "proxy",
    "JMSPropertyGroup": [{
      "AssetID": "^\\d+$",
      "Type": "^8$",
      "DirName": ".",
      "ZipCode": "^\\d\\d\\d$"
    }],
    "TimeToLive": "14400",
    "Heartbeat": "300",
    "Option": "1",
    "MaxRetry": "3",
    "Capacity": "24",
    "DisplayMask": "71",
    "StringProperty": {
      "FileName": "",
      "AssetID": "",
      "Type": "",
      "ZipCode": ""
    },
    "Monitor": {
      "Name": "age_##AssetID##",
      "ClassName": "org.qbroker.monitor.AgeMonitor",
      "Site": "FAM",
      "Type": "AgeMonitor",
      "Category": "MONITOR",
      "Description": "wait on the file",
      "URI": "script:///fsfileinfo",
      "Script": "/opt/qbroker/bin/fileinfo.sh ##DirName##/8/main/##ZipCode##/##AssetID##.8",
      "Timeout": "45",
      "Pattern": "\\s+Last Modification: (\\d\\d-\\w+-\\d\\d\\d\\d \\d\\d:\\d\\d:\\d\\d)",
      "DateFormat": "dd-MMM-yyyy HH:mm:ss",
      "Step": "1",
      "Tolerance": "0",
      "MaxRetry": "2",
      "MaxPage": "1",
      "ExceptionTolerance": "-1",
      "ActiveTime": {
        "TimeWindow": [{
          "Interval": "00:00:00-24:00:00",
          "Threshold": "-1800"
        }]
      }
    },
    "EventPattern": [{
      "status": "^(OCCURRED|Occurred)$"
    }]
  },{
    "Name": "avi",
    "JMSPropertyGroup": [{
      "Type": "^1$",
      "AssetID": "^\\d+$",
      "DirName": ".",
      "ZipCode": "^\\d\\d\\d$"
    ]},
    "TimeToLive": "64800",
    "Heartbeat": "600",
    "MaxRetry": "3",
    "Option": "1",
    "Capacity": "8",
    "DisplayMask": "71",
    "StringProperty": {
      "DirName": "",
      "AssetID": "",
      "Type": "",
      "ZipCode": ""
    },
    "Monitor": {
      "Name": "avi_##AssetID##",
      "ClassName": "org.qbroker.monitor.AgeMonitor",
      "Site": "FAM",
      "Type": "AgeMonitor",
      "Category": "MONITOR",
      "Description": "wait on the file",
      "URI": "script:///fsfileinfo",
      "Script": "/opt/qbroker/bin/fileinfo.sh ##DirName##/1/main/##ZipCode##/##AssetID##.1",
      "Timeout": "45",
      "Pattern": "\\s+Last Modification: (\\d\\d-\\w+-\\d\\d\\d\\d \\d\\d:\\d\\d:\\d\\d)",
      "DateFormat": "dd-MMM-yyyy HH:mm:ss",
      "Step": "1",
      "Tolerance": "0",
      "MaxRetry": "2",
      "MaxPage": "1",
      "ExceptionTolerance": "-1",
      "EmptyDataIgnored": "false",
      "DependencyGroup": [{
        "Dependency": [{
          "Name": "avi",
          "Type": "FileTester",
          "URI": "file://##DirName##/1/transformed",
          "Pattern": "^##AssetID##(-....)?\\.avi(\\.err)?$",
          "DisableMode": "-1"
        }]
      }],
      "ActiveTime": {
        "TimeWindow": [{
          "Interval": "00:00:00-24:00:00",
          "Threshold": "01:30:00,02:00:00,02:30:00"
        }]
      }
    },
    "EventPattern": [{
      "status": "^(NORMAL|Normal|Disabled|DISABLED)$"
    }]
  }],
  "OutLink": ["pool", "done", "null", {
    "Name": "failure",
    "Capacity": "32",
    "Partition": "12,4"
  },{
    "Name": "nohit",
    "Capacity": "32",
    "Partition": "12,4"
  }
}
where there are two rulesets with different hearteats. The properties of the monitor instances are defined in the block of Monitor. There are 3 variables, ##AssetID##, ##DirName## and ##ZipCode##, in it. Their values are supposed to be provided by the request message. It means the request message must have those properties well defined, also as required by the filter of JMSProppertyGroup. Frequently, the node dispatches the active monitors to the pool. Then it tries to collect the events sent from the monitors. If an event matches the EventPattern, the monitor will be terminated and a new event will be escalated.