Workflow Tracer 2 of 4: Module Primer
(Links to parts: Part 1, Part 2, Part 3, Part 4)
Now that I’ve given a primer on workflows, it is important to discuss modules a bit. The following discussion is generalized. Modules are nothing if not powerful, flexible, and completely open-ended. Therefore, while I am confident that this discussion will be conceptually helpful, understand that there can be deviations from these generalizations.
First, it’s worth noting that there are four basic module types: DataSource, ProbeAction, ConditionDetection, and WriteAction. This is also the order in which they appear, both as children of the ModuleTypes element in the management pack and as children of the MemberModules element of a Composite module.
- DataSource and ProbeAction modules essentially do some work to collect some attributes of some entity and produce a DataItem. These modules can be thought of as operating on entities extenal to OpsMgr itself in a manner that does not change them (i.e. read only) for the expressed purpose of brining the “facts” about their current state of configuration or operation into OpsMgr’s universe. A DataItem produced by a DataSource or ProbeAction is the unit of information that starts that process.
- ConditionDetection modules are essentially filters that consume a DataItem as input and either manipulate it or check it against some conditions. ConditionDetection modules are always defined with an OutputType, but depending on their purpose and the contents of the input, they may or may not output a DataItem on any given occasion. When a ConditionDetection module produces a DataItem, it will be passed on to the next module in the workflow, either unchanged (e.g. as is the case with the expression filters) or transformed (e.g. as is the case with the discovery mappers). When a ConditionDetection module does not produce a DataItem, the workflow ends (e.g. as is the case when a test condition is not met). These modules can be thought of as operating on the DataItem produced by the DataSource or ProbeAction module. They are usually internal to the workflow, meaning that they only consider the input and their purpose and configuration. They do not usually use data external to the data flowing through the workflow. I reiterate, though, that they do not strictly need to be simple filters that can only see the DataItem passed in or only affect the DataItem passed out. Some do quite a bit more than that. Good examples of this are the ConditionDetection modules involved in calculating delta values and baselines. They do operate on incoming DataItems and produce outgoing DataItems, but they also hold state themselves.
- WriteAction modules receive a DataItem and do something active with it, like write it to the database, generate an alert, or otherwise use its contents to affect some other entity. These are formally defined as the only modules that will change something external to OpsMgr. This is one reason why you don’t normally see a WriteAction module in a discovery or monitor. WriteAction modules optionally can produce output.
See the following diagram for a visual treatment of the four module types.
This, therefore, gives a lifecycle of a workflow: from the creation of a DataItem, through manipulations, to the final action a DataItem causes. Of course, to continue painting a picture of how these modules are used, I would also note that discoveries and monitors do not usually contain write actions. The nature of a discovery or monitor infers that their end state will be internal to OpsMgr: a new or updated instance or a change in state, respectively. In those cases, then, it is OpsMgr itself that consumes the final output of the workflow.
The next two paragraphs contain very rich information. Based on feedback, I have added a few diagrams to help understand these concepts. I suggest an initial read of these two paragraphs, followed by a review of the diagrams, and then a quick re-read.
To make matters even more interesting, the definition/implementation of any given module can be one of three forms: native code (implemented as a COM .DLL), managed code (implemented as a .NET assembly .DLL), or a Composite module. A Composite module is itself a pre-defined sequence of other modules. Composite modules are the most interesting to research, since a Composite can be defined as the sequence of several modules, each of which may be a Composite itself, each of which yet again may be a Composite, etc. Eventually, all module implementations will end at native or managed code, but it can be quite a ride getting there. Since any given module will be of one of four module types implemented in one of three possible ways, how truly open-ended a module’s functionality can be should be self-evident. I have written a tool for examining such lineages in OpsMgr, which you can read about here. It actually started out as a tool that would only explore the lineage of modules, but I later expanded it to include class types, relationship types, and data types.
This also skews the clean definitions and characterizations of the four module types I discussed above. Consider this: a DataSourceModuleType may be defined as a Composite of a DataSource, a ProbeAction, and a ConditionDetection module. Another DataSourceModuleType may use that DataSource module in its own definition of a Composite that includes another ProbeAction and another ConditionDetection module. That would make the final DataSourceModuleType a DataSource, ProbeAction, ConditionDetection, ProbeAction, and finally ConditionDetection sequence. That final DataSourceModuleType might then be used in a workflow for a Discovery rule. Although only certain combinations are allowed for each composite type (i.e. a ConditionDetection module may not come between a DataSource and ProbeAction in a Composite DataSourceModuleType), it’s otherwise completely flexible.
The following diagrams help to present this material more visually.
The first diagram presents some basic modules that will be used in the examples that follow:
The next diagram depicts how Composite modules are created and eventually used in a workflow:
The next diagram shows a more detailed view of the workflow presented above (the Rule):
This next diagram shows how the Composite modules may also be used with other modules to form a UnitMonitorType. This next diagram is an example of a two-state monitor (Healthy/Warning or Healthy/Critical):
This final example extends the previous example to be a three-state monitor (Healthy/Warning/Critical):
Obviously, it can get fairly complicated. On the other hand, it is very conducive to good design habits: making small, focused bits of functionality that are then re-used where they are needed.
Next in part 3, we will examine these DataItems a bit more closely.
VJD/<><
(Links to parts: Part 1, Part 2, Part 3, Part 4)