Skip to content

Commit

Permalink
add new definition migration endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
hu-ahmed committed Jan 27, 2025
1 parent 014d36d commit 5d5b2f8
Show file tree
Hide file tree
Showing 11 changed files with 1,171 additions and 2 deletions.
137 changes: 137 additions & 0 deletions documentation/src/main/resources/openapi/ditto-api-2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,92 @@ paths:
* a string: `"value"` - Currently the definition should follow the pattern: [_a-zA-Z0-9\-]:[_a-zA-Z0-9\-]:[_a-zA-Z0-9\-]
* an empty string: `""`
* `null`: the definition will be deleted
/api/2/things/{thingId}/migrateDefinition:
put:
summary: Migrate Thing Definition
description: |-
Migrate the definition of a Thing with the given `thingId`. The update includes a new definition URL and optional migration payload.
The operation will merge the provided data into the existing thing. If `initializeProperties` is set to `true`, missing properties will be initialized.
**Example usage:**
```json
{
"thingDefinitionUrl": "https://models.example.com/thing-definition-1.0.0.tm.jsonld",
"migrationPayload": {
"attributes": {
"manufacturer": "New Corp",
"location": "Berlin, main floor"
},
"features": {
"thermostat": {
"properties": {
"status": {
"temperature": {
"value": 23.5,
"unit": "DEGREE_CELSIUS"
}
}
}
}
}
},
"patchConditions": {
"thing:/features/thermostat": "not(exists(/features/thermostat))"
},
"initializeMissingPropertiesFromDefaults": true
}
```
tags:
- Things
parameters:
- name: thingId
in: path
required: true
description: The unique identifier of the Thing to update.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MigrateThingDefinitionRequest'
responses:
'204':
description: The thing definition was successfully updated.
'400':
description: |-
The request could not be completed. Possible reasons:
* Invalid JSON request body.
* Missing or incorrect values in the request.
content:
application/json:
schema:
$ref: '#/components/schemas/AdvancedError'
'401':
description: The request could not be completed due to missing authentication.
content:
application/json:
schema:
$ref: '#/components/schemas/AdvancedError'
'403':
description: The caller does not have permission to update the thing definition.
content:
application/json:
schema:
$ref: '#/components/schemas/AdvancedError'
'404':
description: The thing with the specified ID was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/AdvancedError'
'412':
$ref: '#/components/responses/PreconditionFailed'
'424':
$ref: '#/components/responses/DependencyFailed'

delete:
summary: Delete the definition of a specific thing
description: Deletes the definition of the thing identified by the `thingId`.
Expand Down Expand Up @@ -9273,6 +9359,57 @@ components:
required:
- thingId
- policyId
MigrateThingDefinitionRequest:
type: object
description: JSON payload to update the definition of a Thing.
properties:
thingDefinitionUrl:
type: string
format: uri
description: "The URL of the new Thing definition to be applied."
example: "https://models.example.com/thing-definition-1.0.0.tm.jsonld"
migrationPayload:
type: object
description: "Optional migration payload with updates to attributes and features."
properties:
attributes:
type: object
additionalProperties: true
description: "Attributes to be updated in the thing."
example:
manufacturer: "New Corp"
location: "Berlin, main floor"
features:
type: object
additionalProperties:
type: object
properties:
properties:
type: object
additionalProperties: true
description: "Features to be updated in the thing."
example:
thermostat:
properties:
status:
temperature:
value: 23.5
unit: "DEGREE_CELSIUS"
patchConditions:
type: object
description: "Optional conditions to apply the migration only if the existing thing matches the specified values."
additionalProperties:
type: string
example:
thing:/features/thermostat: "not(exists(/features/thermostat))"
initializeMissingPropertiesFromDefaults:
type: boolean
description: "Flag indicating whether missing properties should be initialized with default values."
example: true
required:
- thingId
- thingDefinitionUrl
- migrationPayload
NewPolicy:
type: object
description: Policy consisting of policy entries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ paths:
$ref: "./paths/things/index.yml"
'/api/2/things/{thingId}':
$ref: "./paths/things/thing.yml"
'/api/2/things/{thingId}/MigrateDefinition':
$ref: "./paths/things/thing.yml"
'/api/2/things/{thingId}/definition':
$ref: "./paths/things/definition.yml"
'/api/2/things/{thingId}/policyId':
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2020 Contributors to the Eclipse Foundation
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
Expand Down Expand Up @@ -502,6 +502,82 @@ patch:
smartMode: null
tempToHold: 50
description: JSON representation of the thing to be patched.
/post:
summary: Update the definition of an existing Thing
description: |-
Updates the definition of the specified thing by providing a new definition URL along with an optional migration payload.
The request body allows specifying:
- A new Thing definition URL.
- A migration payload containing updates to attributes and features.
- Patch conditions to ensure consistent updates.
- Whether properties should be initialized if missing.
### Example:
```json
{
"thingDefinitionUrl": "https://example.com/new-thing-definition.json",
"migrationPayload": {
"attributes": {
"manufacturer": "New Corp"
},
"features": {
"sensor": {
"properties": {
"status": {
"temperature": {
"value": 25.0
}
}
}
}
}
},
"patchConditions": {
"thing:/features/sensor": "not(exists(/features/sensor))"
},
"initializeMissingPropertiesFromDefaults": true
}
```
tags:
- Things
parameters:
- $ref: '../../parameters/thingIdPathParam.yml'
requestBody:
description: JSON payload containing the new definition URL, migration payload, patch conditions, and initialization flag.
required: true
content:
application/json:
schema:
$ref: '../../schemas/things/migrateThingDefinitionRequest.yml'
responses:
'204':
description: The thing definition was successfully updated. No content is returned.
'400':
description: The request could not be processed due to invalid input.
content:
application/json:
schema:
$ref: '../../schemas/errors/advancedError.yml'
'401':
description: Unauthorized request due to missing authentication.
content:
application/json:
schema:
$ref: '../../schemas/errors/advancedError.yml'
'404':
description: The specified thing could not be found.
content:
application/json:
schema:
$ref: '../../schemas/errors/advancedError.yml'
'412':
description: The update conditions were not met.
content:
application/json:
schema:
$ref: '../../schemas/errors/advancedError.yml'
delete:
summary: Delete a specific thing
description: |-
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0
#
# SPDX-License-Identifier: EPL-2.0
type: object
description: JSON payload to migrate the definition of a Thing.

properties:
thingDefinitionUrl:
type: string
format: uri
description: "The URL of the new Thing definition to be applied."
example: "https://models.example.com/thing-definition-1.0.0.tm.jsonld"

migrationPayload:
type: object
description: "Optional migration payload with updates to attributes and features."
properties:
attributes:
type: object
additionalProperties: true
description: "Attributes to be updated in the thing."
example:
manufacturer: "New Corp"
location: "Berlin, main floor"
features:
type: object
additionalProperties:
type: object
properties:
properties:
type: object
additionalProperties: true
description: "Features to be updated in the thing."
example:
thermostat:
properties:
status:
temperature:
value: 23.5
unit: "DEGREE_CELSIUS"

patchConditions:
type: object
description: "Optional conditions to apply the migration only if the existing thing matches the specified values."
additionalProperties:
type: string
example:
thing:/features/thermostat: "not(exists(/features/thermostat))"

initializeMissingPropertiesFromDefaults:
type: boolean
description: "Flag indicating whether missing properties should be initialized with default values."
example: true

required:
- thingId
- thingDefinitionUrl
- migrationPayload
33 changes: 33 additions & 0 deletions documentation/src/main/resources/pages/ditto/httpapi-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,39 @@ The following additional API endpoints are automatically available:
* `/things/{thingId}/features/lamp/properties/color`: accessing the `color` properties of the feature `lamp` of the
specific thing

#### `/things` in API 2 - update-definition
Migrate Thing Definitions
The endpoint `/things/{thingId}/migrateDefinition`allows migrating the thing definition with a new model, as well as optionally migrating attributes and features.

HTTP Method: POST /things/{thingId}/migrateDefinition
Request Example
```json
{
"thingDefinitionUrl": "https://models.example.com/thing-definition-1.0.0.tm.jsonld",
"migrationPayload": {
"attributes": {
"manufacturer": "New Corp",
"location": "Berlin, main floor"
},
"features": {
"thermostat": {
"properties": {
"status": {
"temperature": {
"value": 23.5,
"unit": "DEGREE_CELSIUS"
}
}
}
}
}
},
"patchConditions": {
"thing:/features/thermostat": "not(exists(/features/thermostat))"
},
"initializeMissingPropertiesFromDefaults": true
}
```
#### `/policies` in API 2

The base endpoint for accessing and working with `Policies`.<br/>
Expand Down
Loading

0 comments on commit 5d5b2f8

Please sign in to comment.