thingsboard / thingsboard

Open-source IoT Platform - Device management, data collection, processing and visualization.
https://thingsboard.io
Apache License 2.0
17.58k stars 5.2k forks source link

[Bug] params value of RPC "method":"gateway_device_deleted" is not a JSON encoded string #9769

Open skewty opened 11 months ago

skewty commented 11 months ago

Describe the bug The params value of RPC payload is not valid JSON when method=gateway_device_deleted is sent by back-end.

To Reproduce

import json
RAW_MQTT_PAYLOAD = b'{"method":"gateway_device_deleted","params":"Temp Device 1701728569"}'
rpc_data = json.loads(RAW_MQTT_PAYLOAD)
rpc_params = json.loads(rpc_data.get("params", "{}"))
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Expected behavior params field should have surrounding " character so it is valid JSON.

Docs at https://thingsboard.io/docs/user-guide/rpc/ state params field "value is a JSON.".

A string without surrounding quotes is not JSON.

This is a bug in your back-end and in your gateway.

This bug existed in 3.5. and continues to exist in 3.6..

skewty commented 11 months ago

Perhaps it is better to change the value of params to have a JSON object schema instead.

example:

{ 
  "version": 2,
  "deletedDeviceName": "Temp Device 1701728569" 
}

instead of

Temp Device 1701728569

The schema / params change would also make sense for gateway_device_renamed as well.

{ 
   "version": 2,
   "previousDeviceName": "Temp Device 1701728569",
   "currentDeviceName": "My Device"  
}

instead of

{ "Temp Device 1701728569": "My Device" }

Then params would always be a JSON object.

skewty commented 11 months ago

Looking further into RPC params and I see more inconsistencies.

Example: gateway stats uses camelCase (which is good / expected)

{
  "eventsProduced": 0, 
  "eventsSent": 0
}

but gateway version uses snake_case (which is bad / unexpected)

{
  "current_version": "0",
  "latest_version": "0"
}

gateway devices should be an array of objects so it can be validated using JSON schema but instead it returns a mapping which is (bad / unexpected)

gateway ping uses a string which could be easily changed to

{ 
   "version": 2,
   "timestamp": "2023-12-05T11:40:12.431363Z"
}

It seems logical for all gateway responses to be a JSON object so they can share more code path.