Find business rules as decision tables
io.moderne.mainframe.rules.FindBusinessRulesio.moderne.recipe:recipes-mainframeOptions
Usage
Run this recipe
This recipe has no required configuration options. Users of Moderne can run it via the Moderne CLI.
You will need to have configured the Moderne CLI on your machine before you can run the following command.
mod run . --recipe FindBusinessRules
To also set the recipe's optional settings, add them to the command. The values below are examples, not recommendations; see Options for what each one does.
mod run . --recipe FindBusinessRules --recipe-option "includeInternalFields=true"
If the recipe is not available locally, then you can install it using:
RELEASE resolves to the newest release and LATEST to the newest build of any kind, including snapshots. Either one lets mod config recipes upgrade pull in later versions without editing this command; a pinned version stays where you put it.
- RELEASE
- LATEST
- Pinned version
mod config recipes jar install io.moderne.recipe:recipes-mainframe:RELEASE
mod config recipes jar install io.moderne.recipe:recipes-mainframe:LATEST
mod config recipes jar install io.moderne.recipe:recipes-mainframe:0.1.0
Data tables
Business rules
io.moderne.mainframe.analysis.table.BusinessRulesOne row per decision: a condition a program tests, and everything that follows from it. A record copied field by field is one decision here, not one per field — the individual assignments are in the rule actions table.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.BusinessRules
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section the actions are written in. The same test made in two places is two decisions, however alike they read. |
| When | The conditions that must all hold, normalised: condition names expanded to the test they stand for, negation folded into the operator, and each field named where its value came from rather than where it was copied to. |
| Then | What the program does, short enough to read. Fields copied unchanged are counted rather than listed, since a record copied field by field is one act however many statements it takes. |
| Decides | Every field assigned and resource acted on, in source order. |
| Actions | How many statements the decision covers. |
| Kinds | What sorts of thing it does: COPY, CONSTANT, COMPUTE, CALL, WRITE. A decision that only copies is plumbing; one that computes or writes is where the business is. |
| Conditions | The fields the condition tests. |
| Inherited from | Fields tested under a name other than the one the source wrote, because the value was traced back through a MOVE to where it came from. |
| Anomaly | CONTRADICTORY, UNREACHABLE or SUBSUMED where the decision cannot do what it appears to; empty otherwise. |
Rule actions
io.moderne.mainframe.analysis.table.RuleActionsOne row per statement a rule decides, which is the grain impact analysis and lineage want: every field the program assigns under a condition, and the condition. Rows sharing a subject are the rows of one decision table; rows sharing a condition are one row of the business rules table.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.RuleActions
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Paragraph | The paragraph or section the action is written in. |
| Subject | What the action decides: the field it assigns, or the resource it acts on. Every row sharing this value belongs to one decision table. |
| Rule | The rule's position in its decision table, in source order. Where two rules cover the same case, the later one is the one that runs. |
| When | The conditions that must all hold, normalised. |
| Then | What happens: the value assigned, or the operation performed. |
| Kind | COPY for a field given another field's value unchanged, CONSTANT for a literal, COMPUTE for arithmetic or an expression, CALL for work handed to another program, WRITE for something written where the outside can see it. |
| Conditions | The fields this rule tests, which are the columns of its decision table. |
| Inherited from | Fields the rule tests under a name other than the one the source wrote, because the value was traced back through a MOVE to where it came from. |
| Anomaly | CONTRADICTORY, UNREACHABLE or SUBSUMED where the rule cannot do what it appears to; empty otherwise. |
Decision table anomalies
io.moderne.mainframe.analysis.table.DecisionTableAnomaliesRules that cannot do what they appear to, found by checking the normalised table rather than by reading the code.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.DecisionTableAnomalies
| Column | Description |
|---|---|
| Program | The COBOL program. |
| Subject | The field or resource the rule decides, which is the decision table it belongs to. |
| Kind | CONTRADICTORY for conditions that exclude each other, so the rule never fires; UNREACHABLE for a rule in a paragraph nothing reaches; SUBSUMED for a rule an earlier one has already decided. |
| Rule | The rule, as WHEN conditions THEN outcome. |
| Paragraph | The paragraph or section the rule is written in. |
| Detail | Why the rule cannot fire, or which earlier rule already covers it. |
Findings
io.moderne.mainframe.analysis.table.FindingsEverything the mainframe analyses found wrong, ranked, with the evidence for each and the line it is on. Sort on priority.
mod study . --last-recipe-run \
--data-table io.moderne.mainframe.analysis.table.Findings
| Column | Description |
|---|---|
| Priority | 1 for CRITICAL down to 4 for LOW, so the table sorts. |
| Severity | CRITICAL for code that cannot do what it was written to do, HIGH for what will break a migration if not decided deliberately, MEDIUM for what is worth knowing first, LOW for cleanup. |
| Category | What kind of problem it is, which is what groups the report into sections: DEAD_RULE, UNREACHABLE_CODE, COPYBOOK_DRIFT, MIGRATION_BLOCKER, RANGE_PATHOLOGY, DEAD_DATA, COMPLEXITY, LAYOUT_DRIFT, IMS_PCB_MISMATCH, IMS_SEGMENT_NOT_SENSITIVE, IMS_IO_AREA_MISMATCH, MFS_MESSAGE_LENGTH, SCREEN_ITEM_UNREACHED, SCREEN_FIELD_UNREACHED, PARSE_FAILURE, UNDOCUMENTED, STALE_DOCUMENTATION, STALE_REFERENCE, UNENFORCED_BUILD_ORDER, UNSCHEDULED_JOB, AUTOCALL_RESOLVED_REFERENCE, UNRESOLVED_EXECUTION_PATH, INHERITED_SETTING, UNLOAD_NEEDS_REDESIGN, UNLOAD_ACCESS_MODE, UNLOAD_CONSISTENCY, UNLOAD_OUTPUT_WIRING, MIXED_SUBSTITUTION. |
| Program | The COBOL program, or the copybook where the finding is about one. |
| Summary | The finding in one sentence, written to be read on its own. |
| Evidence | Why this is claimed — the conditions that conflict, the two declarations that differ, the caller that made the paragraph unreachable. A finding nobody can check is a finding nobody will act on. |
| Where | The paragraph, section or data item the finding is in. |
| Source path | The file, so the finding can be opened. |
Source files that had results
org.openrewrite.table.SourcesFileResultsSource files that were modified by the recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SourcesFileResults
| Column | Description |
|---|---|
| Source path before the run | The source path of the file before the run. null when a source file was created during the run. |
| Source path after the run | A recipe may modify the source path. This is the path after the run. null when a source file was deleted during the run. |
| Parent of the recipe that made changes | In a hierarchical recipe, the parent of the recipe that made a change. Empty if this is the root of a hierarchy or if the recipe is not hierarchical at all. |
| Recipe that made changes | The specific recipe that made a change. |
| Estimated time saving | An estimated effort that a developer to fix manually instead of using this recipe, in unit of seconds. |
| Cycle | The recipe cycle in which the change was made. |
Source files that had search results
org.openrewrite.table.SearchResultsSearch results that were found during the recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SearchResults
| Column | Description |
|---|---|
| Source path of search result before the run | The source path of the file with the search result markers present. |
| Source path of search result after run the run | A recipe may modify the source path. This is the path after the run. null when a source file was deleted during the run. |
| Result | The trimmed printed tree of the LST element that the marker is attached to. |
| Description | The content of the description of the marker. |
| Recipe that added the search marker | The specific recipe that added the Search marker. |
Source files that errored on a recipe
org.openrewrite.table.SourcesFileErrorsThe details of all errors produced by a recipe run.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.SourcesFileErrors
| Column | Description |
|---|---|
| Source path | The file that failed to parse. |
| Recipe that made changes | The specific recipe that made a change. |
| Stack trace | The stack trace of the failure. |
Recipe performance
org.openrewrite.table.RecipeRunStatsStatistics used in analyzing the performance of recipes.
mod study . --last-recipe-run \
--data-table org.openrewrite.table.RecipeRunStats
| Column | Description |
|---|---|
| The recipe | The recipe whose stats are being measured both individually and cumulatively. |
| Source file count | The number of source files the recipe ran over. |
| Source file changed count | The number of source files which were changed in the recipe run. Includes files created, deleted, and edited. |
| Cumulative scanning time (ns) | The total time spent across the scanning phase of this recipe. |
| Max scanning time (ns) | The max time scanning any one source file. |
| Cumulative edit time (ns) | The total time spent across the editing phase of this recipe. |
| Max edit time (ns) | The max time editing any one source file. |