Template Engine: add composed member addressing (path-qualified canonical names), override granularity per entity type, semantic validation (call targets, arg types), graph acyclicity enforcement, revision hashes for flattened configs. Deployment Manager: add deployment ID + idempotency, per-instance operation lock covering all mutating commands, state transition matrix, site-side apply atomicity (all-or-nothing), artifact version compatibility policy. Site Runtime: add script trust model (forbidden APIs, execution timeout, constrained compilation), concurrency/serialization rules (Instance Actor serializes mutations), site-wide stream backpressure (per-subscriber buffering, fire-and-forget publish). Communication: add application-level correlation IDs for protocol safety beyond Akka.NET transport guarantees. External System Gateway: add 408/429 as transient errors, CachedCall idempotency note, dedicated dispatcher for blocking I/O isolation. Health Monitoring: add monotonic sequence numbers to prevent stale report overwrites. Security: require LDAPS/StartTLS for LDAP connections. Central UI: add failover behavior (SignalR reconnect, JWT survives, shared Data Protection keys, load balancer readiness). Cluster Infrastructure: add down-if-alone=on for safe singleton ownership. Site Event Logging: clarify active-node-only logging (no replication), add 1GB storage cap with oldest-first purge. Host: add readiness gating (health check endpoint, no traffic until operational). Commons: add message contract versioning policy (additive-only evolution). Configuration Database: add optimistic concurrency on deployment status records.
166 lines
10 KiB
Markdown
166 lines
10 KiB
Markdown
# Component: Template Engine
|
||
|
||
## Purpose
|
||
|
||
The Template Engine is the core modeling component that lives on the central cluster. It manages the definition, inheritance, composition, and resolution of machine templates — the blueprints from which all machine instances are created. It handles flattening templates into deployable configurations, calculating diffs between deployed and current states, and performing comprehensive pre-deployment validation.
|
||
|
||
## Location
|
||
|
||
Central cluster only. Sites receive flattened output and have no awareness of templates.
|
||
|
||
## Responsibilities
|
||
|
||
- Store and manage template definitions (attributes, alarms, scripts) in the configuration database.
|
||
- Enforce inheritance (is-a) relationships between templates.
|
||
- Enforce composition (has-a) relationships, including recursive nesting of feature modules.
|
||
- Detect and reject naming collisions when composing feature modules (design-time error).
|
||
- Resolve the attribute chain: Instance → Child Template → Parent Template → Composing Template → Composed Module.
|
||
- Enforce locking rules — locked members cannot be overridden downstream, intermediate levels can lock previously unlocked members, and nothing can unlock what's locked above.
|
||
- Support adding new attributes, alarms, and scripts in child templates.
|
||
- Prevent removal of inherited members.
|
||
- Flatten a fully resolved template + instance overrides into a deployable configuration (no template structure, just concrete attribute values with resolved data connection bindings).
|
||
- Calculate diffs between deployed and template-derived configurations.
|
||
- Perform comprehensive pre-deployment validation (see Validation section).
|
||
- Provide on-demand validation for Design users during template authoring.
|
||
- Enforce template deletion constraints — templates cannot be deleted if any instances or child templates reference them.
|
||
|
||
## Key Entities
|
||
|
||
### Template
|
||
- Has a unique name/ID.
|
||
- Optionally extends a parent template (inheritance).
|
||
- Contains zero or more composed feature modules (composition).
|
||
- Defines attributes, alarms, and scripts as first-class members.
|
||
- Cannot be deleted if referenced by instances or child templates.
|
||
- Concurrent editing uses **last-write-wins** — no pessimistic locking or conflict detection.
|
||
|
||
### Attribute
|
||
- Name, Value, Data Type (Boolean, Integer, Float, String), Lock Flag, Description.
|
||
- Optional Data Source Reference — a **relative path** within a data connection (e.g., `/Motor/Speed`). The template defines *what* to read but not *where* to read it from. The connection binding is an instance-level concern.
|
||
- Value may be empty if intended to be set at instance level or via data connection binding.
|
||
|
||
### Alarm
|
||
- Name, Description, Priority Level (0–1000), Lock Flag.
|
||
- Trigger Definition: Value Match, Range Violation, or Rate of Change.
|
||
- Optional On-Trigger Script reference.
|
||
|
||
### Script (Template-Level)
|
||
- Name, Lock Flag, C# source code.
|
||
- Trigger configuration: Interval, Value Change, Conditional, or invoked by alarm/other script.
|
||
- Optional minimum time between runs.
|
||
- **Parameter Definition** *(optional)*: Defines input parameters (name and data type per parameter). Scripts without parameters accept no arguments.
|
||
- **Return Value Definition** *(optional)*: Defines the structure of the script's return value (field names and data types). Supports single objects and lists of objects. Scripts without a return definition return void.
|
||
|
||
### Instance
|
||
- Associated with a specific template and a specific site.
|
||
- Assigned to an area within the site.
|
||
- Can override non-locked attribute values (no adding/removing attributes).
|
||
- Bound to data connections at instance creation — **per-attribute binding** where each attribute with a data source reference individually selects its data connection.
|
||
- Can be in **enabled** or **disabled** state.
|
||
- Can be **deleted** — deletion is blocked if the site is unreachable.
|
||
|
||
### Area
|
||
- Hierarchical groupings per site (parent-child).
|
||
- Stored in the configuration database.
|
||
- Used for filtering/organizing instances in the UI.
|
||
|
||
## Composed Member Addressing
|
||
|
||
When a template composes a feature module, members from that module are addressed using a **path-qualified canonical name**: `[ModuleInstanceName].[MemberName]`. For nested compositions, the path extends: `[OuterModule].[InnerModule].[MemberName]`.
|
||
|
||
- All internal references (triggers, scripts, diffs, stream topics, UI display) use canonical names.
|
||
- The composing template's own members (not from a module) have no prefix — they are top-level names.
|
||
- Naming collision detection operates on canonical names, so two modules can define the same member name as long as their module instance names differ.
|
||
|
||
## Override Granularity
|
||
|
||
Override and lock rules apply per entity type at the following granularity:
|
||
|
||
- **Attributes**: Value and Description are overridable. Data Type and Data Source Reference are fixed by the defining level. Lock applies to the entire attribute (when locked, no fields can be overridden).
|
||
- **Alarms**: Priority Level, Trigger Definition (thresholds/ranges/rates), Description, and On-Trigger Script reference are overridable. Name and Trigger Type (Value Match vs. Range vs. Rate of Change) are fixed. Lock applies to the entire alarm.
|
||
- **Scripts**: C# source code, Trigger configuration, minimum time between runs, and parameter/return definitions are overridable. Name is fixed. Lock applies to the entire script.
|
||
- **Composed module members**: A composing template or child template can override non-locked members inside a composed module using the canonical path-qualified name.
|
||
|
||
## Naming Collision Detection
|
||
|
||
When a template composes two or more feature modules, the system must check for naming collisions across:
|
||
- Attribute names
|
||
- Alarm names
|
||
- Script names
|
||
|
||
If any composed module introduces a name that already exists (from another composed module or from the composing template itself), this is a **design-time error**. The template cannot be saved until the conflict is resolved. Collision detection is performed recursively for nested module compositions.
|
||
|
||
## Flattening Process
|
||
|
||
When an instance is deployed, the Template Engine resolves the full configuration:
|
||
|
||
1. Start with the base template's attributes, alarms, and scripts.
|
||
2. Walk the inheritance chain, applying overrides at each level (respecting locks).
|
||
3. Resolve composed feature modules, applying overrides from composing templates (respecting locks).
|
||
4. Apply instance-level overrides (respecting locks).
|
||
5. Resolve data connection bindings — replace connection name references with concrete connection details from the site.
|
||
6. Output a flat structure: list of attributes with resolved values and data source addresses, list of alarms with resolved trigger definitions, list of scripts with resolved code and triggers.
|
||
|
||
## Diff Calculation
|
||
|
||
The Template Engine can compare:
|
||
- The **currently deployed** flat configuration of an instance.
|
||
- The **current template-derived** flat configuration (what the instance would look like if redeployed now).
|
||
|
||
The diff output identifies added, removed, and changed attributes/alarms/scripts.
|
||
|
||
## Pre-Deployment Validation
|
||
|
||
Before a deployment is sent to a site, the Template Engine performs comprehensive validation:
|
||
|
||
- **Flattening**: The full template hierarchy resolves and flattens without errors.
|
||
- **Naming collision detection**: No duplicate attribute, alarm, or script names in the flattened configuration.
|
||
- **Script compilation**: All instance scripts and alarm on-trigger scripts are test-compiled and must compile without errors.
|
||
- **Alarm trigger references**: Alarm trigger definitions reference attributes that exist in the flattened configuration.
|
||
- **Script trigger references**: Script triggers (value change, conditional) reference attributes that exist in the flattened configuration.
|
||
- **Data connection binding completeness**: Every attribute with a data source reference has a data connection binding assigned on the instance, and the bound data connection name exists as a defined connection at the instance's site.
|
||
- **Exception**: Validation does **not** verify that data source relative paths resolve to real tags on physical devices — that is a runtime concern.
|
||
|
||
### Semantic Validation
|
||
|
||
Beyond compilation, the Template Engine performs static semantic checks:
|
||
|
||
- **Script call targets**: `Instance.CallScript()` and `Scripts.CallShared()` targets must reference scripts that exist in the flattened configuration or shared script library.
|
||
- **Argument compatibility**: Parameter count and data types at call sites must match the target script's parameter definitions.
|
||
- **Return type compatibility**: If a script call's return value is used, the return type definition must match the caller's expectations.
|
||
- **Trigger operand types**: Alarm triggers and script conditional triggers must reference attributes with compatible data types (e.g., Range Violation requires numeric attributes).
|
||
|
||
### Graph Acyclicity
|
||
|
||
The Template Engine enforces that inheritance and composition graphs are **acyclic**:
|
||
|
||
- A template cannot inherit from itself or from any descendant in its inheritance chain.
|
||
- A template cannot compose itself or any ancestor/descendant that would create a circular composition.
|
||
- These checks are performed on save.
|
||
|
||
### Flattened Configuration Revision
|
||
|
||
Each flattened configuration output includes a **revision hash** (computed from the resolved content). This hash is used for:
|
||
|
||
- Staleness detection: comparing the deployed revision to the current template-derived revision without a full diff.
|
||
- Diff correlation: ensuring diffs are computed against a consistent baseline.
|
||
|
||
### On-Demand Validation
|
||
|
||
The same validation logic is available to Design users in the Central UI without triggering a deployment. This allows template authors to check their work for errors during authoring.
|
||
|
||
### Shared Script Validation
|
||
|
||
For shared scripts, pre-compilation validation is performed before deployment. Since shared scripts have no instance context, validation is limited to C# syntax and structural correctness.
|
||
|
||
## Dependencies
|
||
|
||
- **Configuration Database (MS SQL)**: Stores all templates, instances, areas, and their relationships.
|
||
- **Security & Auth**: Enforces Design role for template authoring, Deployment role for instance management.
|
||
- **Configuration Database (via IAuditService)**: All template and instance changes are audit logged.
|
||
|
||
## Interactions
|
||
|
||
- **Deployment Manager**: Requests flattened configurations, diffs, and validation results from the Template Engine.
|
||
- **Central UI**: Provides the data model for template authoring, instance management, and on-demand validation.
|