Two of four 8.1 records appear to migrate, while the voice and SMS alarm notification profiles produce only a generic migration-log entry and no visible resources under ignition/data/config/resources/core/com.inductiveautomation.alarm-notification. The number that matters is not the count of success messages; it is the count of source tables represented by the migration strategy. ExtensionPointRecordMigrationStrategy migrates the table META named in its configuration, not every related record reachable from that table.
Wrong fixes and misleading signals
Several reasonable checks fail to address this symptom because the migration can complete without throwing an exception while still omitting related data.
| Attempt or signal | Why it does not settle the problem | Decisive check |
|---|---|---|
| Search the gateway log for warnings or errors | A strategy can process its declared record successfully while leaving undeclared related tables untouched. | Compare every 8.1 table that owns required profile data with every META explicitly handled by a strategy. |
| Treat “migrated” as proof that the profile resource exists | The message confirms that migration logic ran; it does not prove that the expected resource path or every dependent setting was written. | Inspect the resource tree and decode the migrated profile configuration. |
| Assume successful new-install provisioning validates migration | Provisioning creates a complete 8.3 resource from current code. Migration must translate an existing 8.1 record graph into that resource model. | Test provisioning and migration as separate execution paths. |
| Repeat the builder pattern for the same root table | Repeating a strategy does not add coverage for another table unless its META, foreign-key relationship, and encoder are declared. |
Build a source-to-destination field map before changing code. |
Declared META migration boundary
The builder establishes a narrow conversion boundary. In the shown SMS strategy, SmsNotificationExtensionPoint.TYPE_ID identifies the extension-point type, AlarmNotificationProfileConfig.RESOURCE_TYPE selects the destination resource type, and AlarmNotificationProfileRecord.META identifies the profile table handled directly. The settings relationship is described by MessageNotificationProfileSettings.Profile and MessageNotificationProfileSettings.META; the settings encoder then maps that declared settings record into the destination configuration.
The number that matters is the number of persistent record types containing required state. If the 8.1 voice or SMS implementation stores configuration in another table beyond the profile and settings records named in the builder, the extension-point migrator has no implicit instruction to serialize that table. A custom migrator is then required for the additional state.
This is a schema-boundary problem, not a logging problem. The migration framework operates from declared metadata and relationships. A Java reference, extension-point constructor, or runtime association does not automatically expand the persistent records selected for conversion.
Record and resource inventory
Inventory the four expected records before editing the migration strategy. Separate the singleton and account records that already produce destination locations from the two alarm notification records whose destination is unclear. For each notification type, trace the owning profile row, settings row, foreign key, and any module-specific child rows.
| Quantity or identifier | Meaning | Where to read it |
|---|---|---|
| 4 source records | Expected migration population: one singleton, one account record, and two notification records | 8.1 module database records |
| 2 located records | Singleton and account migrations report destination locations | Migration log under ignition/data/config/resources
|
| 2 unresolved profiles | Voice and SMS profiles lack a visible destination location | Migration log and 8.3 resource tree |
AlarmNotificationProfileRecord.META |
Root table explicitly selected by the example strategy | Migration builder and 8.1 record definition |
MessageNotificationProfileSettings.META |
Declared settings table | Migration builder and settings record definition |
MessageNotificationProfileSettings.Profile |
Foreign key connecting settings to the profile | Settings record definition |
ignition/data/config/resources/core/com.inductiveautomation.alarm-notification |
Expected resource area based on successful new-install creation | 8.3 filesystem after provisioning and after migration |
Read the 8.1 record definitions rather than inferring persistence from extension-point code. Mark every field required to reconstruct a working voice or SMS profile, then identify which META owns it. Any required field owned by an undeclared record is outside the builder’s current coverage.
Migration procedure
- Back up the gateway data before repeating the migration. Use a disposable 8.3 test installation so each run begins from a known state.
- List the 8.1 tables associated with each voice and SMS profile. Record the primary record, the value of the profile foreign key, and every child record carrying operational settings.
- Compare that list with the builder. Confirm that the root is represented by
AlarmNotificationProfileRecord.METAand that the declared child is represented byMessageNotificationProfileSettings.META. - Trace
MessageNotificationProfileSettings.Profilein actual source data. Each settings row must reference the intended profile row; a missing or mismatched relationship prevents the builder from assembling the expected configuration. - Review the settings encoder field by field. Map every required property from the declared settings record into the 8.3 configuration. A strategy can run successfully while an incomplete encoder produces a resource that lacks required configuration.
- For each additional 8.1 table containing required profile state, implement a custom migration path or an additional applicable strategy. The custom logic must read the related record, associate it with the correct profile, and encode it into the destination resource structure.
- Run the migration once on a clean test target. Capture the migration log, the resulting resource paths, and the decoded configuration for both profiles.
Keep the SMS and voice mappings separate during diagnosis. They may share a profile base record while using different settings records or encoders. Combining them too early can hide which record boundary remains uncovered.
Destination and behavior verification
Verification has three layers: record count, resource content, and runtime behavior. First, reconcile the expected two notification profiles against the resources actually created beneath ignition/data/config/resources/core/com.inductiveautomation.alarm-notification. A log entry alone does not satisfy this check.
Second, inspect each resource’s decoded configuration. Compare the migrated type, account association, and voice or SMS settings with the corresponding 8.1 values. The extension-point type must match the value represented by SmsNotificationExtensionPoint.TYPE_ID for the SMS strategy; perform the equivalent check for the voice strategy using its declared type.
Third, load the profiles through the 8.3 gateway configuration and perform a controlled functional test. Confirm that each profile can resolve its account data and execute its intended notification path. If a resource exists but cannot load, inspect the resource configuration and gateway log for a decoding or type-registration failure. If it loads but lacks settings, return to the encoder and source-table inventory.
Recurring migration pitfalls
Partial schemas are the dominant failure mode. A base profile row may contain identity and type information while a module-specific table contains delivery settings. Migrating only the base row can therefore look successful but yield no usable profile.
Another trap is treating new-install creation as an end-to-end migration test. The creation path already has current objects and can write the final resource directly. The migration path starts with legacy rows, depends on valid foreign keys, and must explicitly translate every required value.
Repeated test runs can also obscure the result when earlier resources remain on disk. Use a clean target or document the pre-run resource inventory so newly created resources can be distinguished from stale ones. Preserve the failing source dataset until both profiles pass configuration and functional verification.
FAQ
Can I rely on a migration log entry as proof that the profile migrated?
No. Reconcile the expected two profiles with the resource tree and inspect each decoded configuration; the entry proves execution, not complete serialization.
Does ExtensionPointRecordMigrationStrategy migrate every related table?
No. It migrates the table META called out directly and the settings relationship explicitly supplied to the builder. Add custom migration logic for required state stored elsewhere.
Can I use successful 8.3 profile provisioning to validate my migration code?
It validates current resource creation and extension-point registration, but not legacy record translation. Test an actual 8.1 dataset through the migration path.
Does a missing resource path mean the extension-point TYPE_ID is wrong?
Not by itself. First verify the source foreign key, declared META records, encoder coverage, and destination resource count; then inspect type registration if a created resource fails to load.
When should I stop debugging the 8.3 migration and contact official support?
Stop after a clean migration still omits a profile even though every required 8.1 table, foreign key, and encoded field has been traced and captured. Escalate through the official Inductive Automation support channel with the module version, minimal record definitions, migration strategy, migration log, gateway log, and sanitized before-and-after resource inventory.