-
Notifications
You must be signed in to change notification settings - Fork 262
Description
Description
Motivation / Use Case
When migrating a Thing to a new definition using the POST /things/{thingId}/migrateDefinition endpoint, the migrationPayload currently only accepts static (literal) values. This makes it impossible to dynamically copy or transform existing data from the Thing during migration.
Consider a scenario where a Thing's definition evolves and a field is renamed or moved:
- Old definition: Temperature stored at
features/sensor/properties/temp - New definition: Temperature stored at
features/sensor/properties/status/currentTemperature
Currently, the migration must either:
- Provide a hardcoded default value (losing the existing data), or
- Require a separate API call to read the Thing first, extract the value, then include it in the migration payload
Supporting the {{ thing-json:<json-path> }} placeholder in the migrationPayload would allow users to reference and copy data from the existing Thing in a single migration request.
Proposed Solution
Enable placeholder resolution (specifically thing-json) in the migrationPayload of the MigrateThingDefinition command before merging it with the existing Thing.
The thing-json placeholder already exists in Ditto (used in Connections for outbound message transformation) and allows extracting arbitrary values from a Thing's JSON representation using JsonPointer notation.
Example
Existing Thing (before migration):
{
"thingId": "org.eclipse.ditto:my-device",
"definition": "https://models.example.com/sensor-v1.0.0.tm.jsonld",
"attributes": {
"manufacturer": "ACME Corp",
"location": "Building A, Floor 3"
},
"features": {
"sensor": {
"properties": {
"temp": 23.5,
"humidity": 65
}
}
}
}Migration Request with placeholder support:
POST /api/2/things/org.eclipse.ditto:my-device/migrateDefinition{
"thingDefinitionUrl": "https://models.example.com/sensor-v2.0.0.tm.jsonld",
"migrationPayload": {
"features": {
"sensor": {
"properties": {
"status": {
"currentTemperature": "{{ thing-json:features/sensor/properties/temp }}",
"currentHumidity": "{{ thing-json:features/sensor/properties/humidity }}",
"lastKnownLocation": "{{ thing-json:attributes/location }}"
}
}
}
}
}
}Resulting Thing (after migration):
{
"thingId": "org.eclipse.ditto:my-device",
"definition": "https://models.example.com/sensor-v2.0.0.tm.jsonld",
"attributes": {
"manufacturer": "ACME Corp",
"location": "Building A, Floor 3"
},
"features": {
"sensor": {
"properties": {
"temp": 23.5,
"humidity": 65,
"status": {
"currentTemperature": 23.5,
"currentHumidity": 65,
"lastKnownLocation": "Building A, Floor 3"
}
}
}
}
}Additional Use Cases
- Field Renaming: Copy value from old field name to new field name during schema evolution
- Data Restructuring: Move nested data to a different location in the Thing hierarchy
- Field Consolidation: Combine multiple existing values into a new structure
- Conditional Migration: Combined with
patchConditions, copy data only when certain conditions are met
Implementation Considerations
- The
thing-jsonplaceholder infrastructure already exists inImmutableThingJsonPlaceholder(edge-service module) - Resolution should happen against the current state of the Thing before any migration changes are applied
- Type coercion: The resolved value should preserve its original JSON type (number, boolean, string, object, array) rather than converting everything to strings
- Non-existent paths: When a referenced path doesn't exist, the placeholder should either:
- Resolve to
null/ be omitted from the result, or - Fail the migration with a clear error message
- Resolve to
- Pipeline functions: Consider supporting the existing pipeline functions (e.g.,
{{ thing-json:attributes/name | fn:upper() }})
Acceptance Criteria
- The
migrationPayloadinMigrateThingDefinitionsupports{{ thing-json:<json-path> }}placeholders - Placeholders are resolved against the Thing's state before any migration changes
- Resolved values preserve their original JSON type (not converted to string)
- Missing paths are handled gracefully (either with null/omission or clear error)
- Dry-run mode (
?dry-run=true) shows the resolved payload in the response - Documentation updated to describe placeholder support in migration payload
- Unit tests cover: valid paths, missing paths, nested objects, arrays, type preservation
Related
- Existing placeholder documentation: Basic Placeholders
ImmutableThingJsonPlaceholderimplementation inedge/serviceMigrateThingDefinitionStrategyinthings/service
Metadata
Metadata
Assignees
Labels
Type
Projects
Status